@opengeni/db 0.28.9 → 0.36.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.
- package/dist/attached-browser-devices.d.ts +42 -0
- package/dist/attempt-tool-catalogs.d.ts +16 -0
- package/dist/browser-auth.d.ts +299 -0
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +137 -0
- package/dist/browser-sessions.d.ts +354 -0
- package/dist/browser-state-artifacts.d.ts +91 -0
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-components.d.ts +37 -0
- package/dist/capability-integrations.d.ts +194 -0
- package/dist/chunk-5KTIEDX7.js +13200 -0
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/chunk-CQZ4QSP5.js +995 -0
- package/dist/chunk-CQZ4QSP5.js.map +1 -0
- package/dist/chunk-F32YT7MP.js +117 -0
- package/dist/chunk-F32YT7MP.js.map +1 -0
- package/dist/chunk-JC5QPLUM.js +666 -0
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/chunk-P3RE4D2B.js +3535 -0
- package/dist/chunk-P3RE4D2B.js.map +1 -0
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/chunk-VKLB2ZGI.js +2389 -0
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/codemode-operations.d.ts +117 -0
- package/dist/codex-token-resolver.d.ts +2 -2
- package/dist/company-profile-schema.d.ts +798 -0
- package/dist/company-profile.d.ts +268 -0
- package/dist/computer-sessions.d.ts +109 -0
- package/dist/connection-token-resolver.d.ts +9 -4
- package/dist/database.d.ts +57 -3
- package/dist/editable-artifact-durable-export.d.ts +153 -0
- package/dist/editable-artifact-durable-export.js +788 -0
- package/dist/editable-artifact-durable-export.js.map +1 -0
- package/dist/editable-artifact-materialization.d.ts +123 -0
- package/dist/editable-artifacts-schema.d.ts +4152 -0
- package/dist/editable-artifacts.d.ts +610 -0
- package/dist/editable-artifacts.js +26 -0
- package/dist/editable-artifacts.js.map +1 -0
- package/dist/generated-images.d.ts +139 -0
- package/dist/index.d.ts +1122 -126
- package/dist/index.js +42329 -18407
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +73 -10
- package/dist/integration-bindings.d.ts +70 -0
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +14 -0
- package/dist/interaction-schema.d.ts +6036 -0
- package/dist/knowledge-source-sync-schema.d.ts +1679 -0
- package/dist/knowledge-source-sync.d.ts +274 -0
- package/dist/memory-governance.d.ts +2 -2
- package/dist/memory-slack-delivery.d.ts +101 -0
- package/dist/new-session-drafts.d.ts +2 -2
- package/dist/pack-components.d.ts +76 -0
- package/dist/pack-installations.d.ts +86 -0
- package/dist/persistence-errors.d.ts +3 -3
- package/dist/plugin-packages.d.ts +126 -0
- package/dist/preference-registry.d.ts +1 -1
- package/dist/provision-roles.d.ts +9 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +19 -6
- package/dist/schema.d.ts +22654 -9359
- package/dist/schema.js +209 -3
- package/dist/scoped-knowledge.d.ts +97 -1
- package/dist/session-control.d.ts +33 -7
- package/dist/session-queue-commands.d.ts +19 -11
- package/dist/session-realtime-context.d.ts +2 -2
- package/dist/session-realtime-ledger.d.ts +4 -4
- package/dist/session-realtime-mirror.d.ts +2 -2
- package/dist/session-realtime-state.d.ts +1 -1
- package/dist/session-realtime-terminal.d.ts +1 -1
- package/dist/session-realtime.d.ts +7 -7
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/session-tool-call-settlement.d.ts +1 -1
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/slack-user-link-access.d.ts +54 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/transcription-recordings.d.ts +2 -2
- package/dist/turn-initiator.d.ts +2 -2
- package/dist/video-generation.d.ts +225 -0
- package/dist/video-generation.js +68 -0
- package/dist/video-generation.js.map +1 -0
- package/dist/workspace-artifacts.d.ts +1 -1
- package/dist/workspace-instruction-policies.d.ts +1 -1
- package/dist/workspace-learning-policy-schema.d.ts +932 -0
- package/dist/workspace-learning-policy.d.ts +161 -0
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
- package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
- package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
- package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
- package/drizzle/0187_generated_image_artifacts.sql +173 -0
- package/drizzle/0188_image_generation_retention_failure.sql +25 -0
- package/drizzle/0189_retained_session_image_formats.sql +13 -0
- package/drizzle/0190_timeline_annotations.sql +31 -0
- package/drizzle/0191_editable_artifact_engine.sql +3853 -0
- package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
- package/drizzle/0193_editable_artifact_authorization.sql +190 -0
- package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
- package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
- package/drizzle/0196_rig_provider_images.sql +152 -0
- package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
- package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
- package/drizzle/0199_workspace_learning_policy.sql +980 -0
- package/drizzle/0201_company_profile_authority.sql +849 -0
- package/drizzle/0202_document_index_checkpoints.sql +85 -0
- package/drizzle/0203_durable_video_generation.sql +353 -0
- package/drizzle/0204_video_generation_funding.sql +44 -0
- package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
- package/drizzle/0206_browser_sessions.sql +646 -0
- package/drizzle/0207_browser_identities.sql +379 -0
- package/drizzle/0208_attached_browser_devices.sql +165 -0
- package/drizzle/0209_computer_sessions.sql +575 -0
- package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
- package/drizzle/0211_editable_artifact_session_links.sql +58 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0212_slack_installation_bindings.sql +348 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0214_session_activity_commit_gate.sql +262 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0215_capabilities_platform.sql +980 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0216_pack_component_ownership.sql +235 -0
- package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +26 -5
- package/src/attached-browser-devices.ts +371 -0
- package/src/attempt-tool-catalogs.ts +131 -0
- package/src/browser-auth.ts +4373 -0
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +1385 -0
- package/src/browser-sessions.ts +2294 -0
- package/src/browser-state-artifacts.ts +449 -0
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-components.ts +166 -0
- package/src/capability-integrations.ts +1571 -0
- package/src/codemode-operations.ts +674 -0
- package/src/company-profile-schema.ts +143 -0
- package/src/company-profile.ts +968 -0
- package/src/computer-sessions.ts +1130 -0
- package/src/connection-token-resolver.ts +270 -25
- package/src/database.ts +468 -24
- package/src/editable-artifact-durable-export.ts +1201 -0
- package/src/editable-artifact-materialization.ts +893 -0
- package/src/editable-artifacts-schema.ts +879 -0
- package/src/editable-artifacts.ts +5404 -0
- package/src/generated-images.ts +740 -0
- package/src/index.ts +9963 -1465
- package/src/insights.ts +251 -23
- package/src/integration-bindings.ts +455 -0
- package/src/integration-facets.ts +862 -0
- package/src/interaction-revisions.ts +70 -0
- package/src/interaction-schema.ts +1606 -0
- package/src/knowledge-source-sync-schema.ts +192 -0
- package/src/knowledge-source-sync.ts +1922 -0
- package/src/memory-slack-delivery.ts +801 -0
- package/src/pack-components.ts +954 -0
- package/src/pack-installations.ts +886 -0
- package/src/persistence-errors.ts +4 -7
- package/src/plugin-packages.ts +1186 -0
- package/src/provision-roles.ts +534 -1
- package/src/runtime-posture-cli.ts +9 -0
- package/src/runtime-posture.ts +721 -5
- package/src/schema.ts +6270 -3159
- package/src/scoped-knowledge-schema.ts +1 -1
- package/src/scoped-knowledge.ts +655 -3
- package/src/session-control.ts +130 -42
- package/src/session-queue-commands.ts +265 -15
- package/src/session-realtime-context.ts +2 -2
- package/src/session-realtime-ledger.ts +3 -3
- package/src/session-realtime.ts +7 -7
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +18 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/slack-user-link-access.ts +702 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +1530 -0
- package/src/workspace-artifacts.ts +1 -1
- package/src/workspace-learning-policy-schema.ts +139 -0
- package/src/workspace-learning-policy.ts +595 -0
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-P6CUHXQZ.js +0 -7248
- package/dist/chunk-P6CUHXQZ.js.map +0 -1
- package/dist/chunk-VHBFHMPC.js +0 -1219
- package/dist/chunk-VHBFHMPC.js.map +0 -1
package/src/scoped-knowledge.ts
CHANGED
|
@@ -84,6 +84,18 @@ export class ScopedKnowledgeAuthorityError extends Error {
|
|
|
84
84
|
readonly name = "ScopedKnowledgeAuthorityError";
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
export class KnowledgeSourceSyncObservationFenceError extends Error {
|
|
88
|
+
readonly name = "KnowledgeSourceSyncObservationFenceError";
|
|
89
|
+
readonly code = "KNOWLEDGE_SOURCE_SYNC_OBSERVATION_FENCE";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export type KnowledgeSourceSyncVersionObservationFence = {
|
|
93
|
+
scheduledTaskRunId: string;
|
|
94
|
+
scanGeneration: number;
|
|
95
|
+
providerRevision: string | null;
|
|
96
|
+
metadataHash: string | null;
|
|
97
|
+
};
|
|
98
|
+
|
|
87
99
|
function iso(value: Date | string): string {
|
|
88
100
|
return (value instanceof Date ? value : new Date(value)).toISOString();
|
|
89
101
|
}
|
|
@@ -808,6 +820,186 @@ export async function upsertKnowledgeSource(
|
|
|
808
820
|
});
|
|
809
821
|
}
|
|
810
822
|
|
|
823
|
+
export async function getKnowledgeSourceForSyncAuthority(
|
|
824
|
+
db: Database,
|
|
825
|
+
input: {
|
|
826
|
+
accountId: string;
|
|
827
|
+
workspaceId: string;
|
|
828
|
+
sourceId: string;
|
|
829
|
+
initiatingSubjectId: string;
|
|
830
|
+
},
|
|
831
|
+
): Promise<{ source: KnowledgeSourceRecord; provider: KnowledgeProviderRecord } | null> {
|
|
832
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
833
|
+
const [row] = await scopedDb
|
|
834
|
+
.select({ source: schema.knowledgeSources, provider: schema.knowledgeProviders })
|
|
835
|
+
.from(schema.knowledgeSources)
|
|
836
|
+
.innerJoin(
|
|
837
|
+
schema.knowledgeProviders,
|
|
838
|
+
and(
|
|
839
|
+
eq(schema.knowledgeProviders.accountId, schema.knowledgeSources.accountId),
|
|
840
|
+
eq(schema.knowledgeProviders.id, schema.knowledgeSources.providerId),
|
|
841
|
+
eq(schema.knowledgeProviders.scopeKey, schema.knowledgeSources.scopeKey),
|
|
842
|
+
),
|
|
843
|
+
)
|
|
844
|
+
.where(
|
|
845
|
+
and(
|
|
846
|
+
eq(schema.knowledgeSources.accountId, input.accountId),
|
|
847
|
+
eq(schema.knowledgeSources.id, input.sourceId),
|
|
848
|
+
),
|
|
849
|
+
)
|
|
850
|
+
.limit(1);
|
|
851
|
+
return row
|
|
852
|
+
? { source: sourceFromRow(row.source), provider: providerFromRow(row.provider) }
|
|
853
|
+
: null;
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
export async function getKnowledgeSourceByExternalIdentityForSyncAuthority(
|
|
858
|
+
db: Database,
|
|
859
|
+
input: {
|
|
860
|
+
accountId: string;
|
|
861
|
+
workspaceId: string;
|
|
862
|
+
providerId: string;
|
|
863
|
+
externalSourceId: string;
|
|
864
|
+
initiatingSubjectId: string;
|
|
865
|
+
},
|
|
866
|
+
): Promise<KnowledgeSourceRecord | null> {
|
|
867
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
868
|
+
const [row] = await scopedDb
|
|
869
|
+
.select()
|
|
870
|
+
.from(schema.knowledgeSources)
|
|
871
|
+
.where(
|
|
872
|
+
and(
|
|
873
|
+
eq(schema.knowledgeSources.accountId, input.accountId),
|
|
874
|
+
eq(schema.knowledgeSources.providerId, input.providerId),
|
|
875
|
+
eq(schema.knowledgeSources.externalSourceId, input.externalSourceId),
|
|
876
|
+
),
|
|
877
|
+
)
|
|
878
|
+
.limit(1);
|
|
879
|
+
return row ? sourceFromRow(row) : null;
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
export async function getKnowledgeSourceAclForSyncAuthority(
|
|
884
|
+
db: Database,
|
|
885
|
+
input: {
|
|
886
|
+
accountId: string;
|
|
887
|
+
workspaceId: string;
|
|
888
|
+
sourceId: string;
|
|
889
|
+
generation: number;
|
|
890
|
+
initiatingSubjectId: string;
|
|
891
|
+
},
|
|
892
|
+
): Promise<KnowledgeSourceAclVersionRecord | null> {
|
|
893
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
894
|
+
const [row] = await scopedDb
|
|
895
|
+
.select()
|
|
896
|
+
.from(schema.knowledgeSourceAclVersions)
|
|
897
|
+
.where(
|
|
898
|
+
and(
|
|
899
|
+
eq(schema.knowledgeSourceAclVersions.accountId, input.accountId),
|
|
900
|
+
eq(schema.knowledgeSourceAclVersions.sourceId, input.sourceId),
|
|
901
|
+
eq(schema.knowledgeSourceAclVersions.generation, input.generation),
|
|
902
|
+
),
|
|
903
|
+
)
|
|
904
|
+
.limit(1);
|
|
905
|
+
return row ? aclFromRow(row) : null;
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
export async function getKnowledgeSourceObjectForSyncAuthority(
|
|
910
|
+
db: Database,
|
|
911
|
+
input: {
|
|
912
|
+
accountId: string;
|
|
913
|
+
workspaceId: string;
|
|
914
|
+
sourceId: string;
|
|
915
|
+
externalObjectId: string;
|
|
916
|
+
initiatingSubjectId: string;
|
|
917
|
+
},
|
|
918
|
+
): Promise<KnowledgeSourceObjectRecord | null> {
|
|
919
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
920
|
+
const [row] = await scopedDb
|
|
921
|
+
.select()
|
|
922
|
+
.from(schema.knowledgeSourceObjects)
|
|
923
|
+
.where(
|
|
924
|
+
and(
|
|
925
|
+
eq(schema.knowledgeSourceObjects.accountId, input.accountId),
|
|
926
|
+
eq(schema.knowledgeSourceObjects.sourceId, input.sourceId),
|
|
927
|
+
eq(schema.knowledgeSourceObjects.externalObjectId, input.externalObjectId),
|
|
928
|
+
),
|
|
929
|
+
)
|
|
930
|
+
.limit(1);
|
|
931
|
+
return row ? objectFromRow(row) : null;
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
export async function getKnowledgeDocumentVersionForSyncAuthority(
|
|
936
|
+
db: Database,
|
|
937
|
+
input: {
|
|
938
|
+
accountId: string;
|
|
939
|
+
workspaceId: string;
|
|
940
|
+
versionId: string;
|
|
941
|
+
initiatingSubjectId: string;
|
|
942
|
+
},
|
|
943
|
+
): Promise<KnowledgeDocumentVersionRecord | null> {
|
|
944
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
945
|
+
const [row] = await scopedDb
|
|
946
|
+
.select()
|
|
947
|
+
.from(schema.knowledgeDocumentVersions)
|
|
948
|
+
.where(
|
|
949
|
+
and(
|
|
950
|
+
eq(schema.knowledgeDocumentVersions.accountId, input.accountId),
|
|
951
|
+
eq(schema.knowledgeDocumentVersions.id, input.versionId),
|
|
952
|
+
),
|
|
953
|
+
)
|
|
954
|
+
.limit(1);
|
|
955
|
+
return row ? versionFromRow(row) : null;
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
export async function getKnowledgeDocumentVersionObservationForSyncAuthority(
|
|
960
|
+
db: Database,
|
|
961
|
+
input: {
|
|
962
|
+
accountId: string;
|
|
963
|
+
workspaceId: string;
|
|
964
|
+
versionId: string;
|
|
965
|
+
initiatingSubjectId: string;
|
|
966
|
+
},
|
|
967
|
+
): Promise<{
|
|
968
|
+
version: KnowledgeDocumentVersionRecord;
|
|
969
|
+
sourceMetadata: Record<string, unknown>;
|
|
970
|
+
sourceUpdatedAt: string | null;
|
|
971
|
+
locationMetadata: Record<string, unknown>;
|
|
972
|
+
documentChunkCount: number;
|
|
973
|
+
} | null> {
|
|
974
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
975
|
+
const [row] = await scopedDb
|
|
976
|
+
.select()
|
|
977
|
+
.from(schema.knowledgeDocumentVersions)
|
|
978
|
+
.where(
|
|
979
|
+
and(
|
|
980
|
+
eq(schema.knowledgeDocumentVersions.accountId, input.accountId),
|
|
981
|
+
eq(schema.knowledgeDocumentVersions.id, input.versionId),
|
|
982
|
+
),
|
|
983
|
+
)
|
|
984
|
+
.limit(1);
|
|
985
|
+
if (!row) return null;
|
|
986
|
+
const [document] = row.documentId
|
|
987
|
+
? await scopedDb
|
|
988
|
+
.select({ chunkCount: schema.documents.chunkCount })
|
|
989
|
+
.from(schema.documents)
|
|
990
|
+
.where(eq(schema.documents.id, row.documentId))
|
|
991
|
+
.limit(1)
|
|
992
|
+
: [];
|
|
993
|
+
return {
|
|
994
|
+
version: versionFromRow(row),
|
|
995
|
+
sourceMetadata: row.sourceMetadata,
|
|
996
|
+
sourceUpdatedAt: optionalIso(row.sourceUpdatedAt),
|
|
997
|
+
locationMetadata: row.locationMetadata,
|
|
998
|
+
documentChunkCount: document?.chunkCount ?? 0,
|
|
999
|
+
};
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
|
|
811
1003
|
export async function appendKnowledgeSourceAclVersion(
|
|
812
1004
|
db: Database,
|
|
813
1005
|
input: Omit<KnowledgeWriteContext, "scope"> & {
|
|
@@ -925,6 +1117,295 @@ export async function appendKnowledgeSourceAclVersion(
|
|
|
925
1117
|
});
|
|
926
1118
|
}
|
|
927
1119
|
|
|
1120
|
+
/** Atomically advance the source ACL to a deny generation and revoke every
|
|
1121
|
+
* materialized retrieval path. Delivery pause alone is never authorization. */
|
|
1122
|
+
export async function deauthorizeKnowledgeSourceRetrieval(
|
|
1123
|
+
db: Database,
|
|
1124
|
+
input: Omit<KnowledgeWriteContext, "scope"> & {
|
|
1125
|
+
sourceId: string;
|
|
1126
|
+
audience: ScopedKnowledgeScope;
|
|
1127
|
+
reasonCode: string;
|
|
1128
|
+
},
|
|
1129
|
+
): Promise<KnowledgeSourceAclVersionRecord> {
|
|
1130
|
+
const reasonCode = normalizedStableKey(input.reasonCode, "reasonCode", 128);
|
|
1131
|
+
return await withKnowledgeWriteRls(db, { ...input, scope: input.audience }, async (scopedDb) => {
|
|
1132
|
+
const [source] = await scopedDb
|
|
1133
|
+
.select()
|
|
1134
|
+
.from(schema.knowledgeSources)
|
|
1135
|
+
.where(eq(schema.knowledgeSources.id, input.sourceId))
|
|
1136
|
+
.limit(1);
|
|
1137
|
+
if (!source) throw new ScopedKnowledgeNotFoundError("Knowledge source was not found");
|
|
1138
|
+
if (source.lifecycleState !== "active") {
|
|
1139
|
+
throw new ScopedKnowledgeInvalidOperationError(
|
|
1140
|
+
"A tombstoned knowledge source cannot be deauthorized",
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1143
|
+
const acl = await appendKnowledgeSourceAclVersion(scopedDb, {
|
|
1144
|
+
accountId: input.accountId,
|
|
1145
|
+
workspaceId: input.workspaceId,
|
|
1146
|
+
sourceId: input.sourceId,
|
|
1147
|
+
audience: input.audience,
|
|
1148
|
+
expectedSourceLifecycleGeneration: source.lifecycleGeneration,
|
|
1149
|
+
expectedAclGeneration: source.currentAclGeneration ?? 0,
|
|
1150
|
+
aclVersion: `opengeni-deny:${reasonCode}`,
|
|
1151
|
+
agentAccess: false,
|
|
1152
|
+
operationId: input.operationId,
|
|
1153
|
+
reasonCode,
|
|
1154
|
+
actor: input.actor,
|
|
1155
|
+
});
|
|
1156
|
+
const revokedAt = new Date();
|
|
1157
|
+
const versions = await scopedDb
|
|
1158
|
+
.select({ documentId: schema.knowledgeDocumentVersions.documentId })
|
|
1159
|
+
.from(schema.knowledgeDocumentVersions)
|
|
1160
|
+
.where(eq(schema.knowledgeDocumentVersions.sourceId, input.sourceId));
|
|
1161
|
+
const documentIds = [
|
|
1162
|
+
...new Set(versions.flatMap((version) => (version.documentId ? [version.documentId] : []))),
|
|
1163
|
+
];
|
|
1164
|
+
await scopedDb
|
|
1165
|
+
.update(schema.knowledgeSourceSyncIndexObligations)
|
|
1166
|
+
.set({
|
|
1167
|
+
status: "invalidated",
|
|
1168
|
+
aclEligibility: "denied",
|
|
1169
|
+
failureCode: reasonCode,
|
|
1170
|
+
updatedAt: revokedAt,
|
|
1171
|
+
})
|
|
1172
|
+
.where(eq(schema.knowledgeSourceSyncIndexObligations.sourceId, input.sourceId));
|
|
1173
|
+
if (documentIds.length > 0) {
|
|
1174
|
+
await scopedDb
|
|
1175
|
+
.update(schema.documents)
|
|
1176
|
+
.set({ agentAccess: false, chunkCount: 0, updatedAt: revokedAt })
|
|
1177
|
+
.where(inArray(schema.documents.id, documentIds));
|
|
1178
|
+
await scopedDb
|
|
1179
|
+
.delete(schema.documentChunks)
|
|
1180
|
+
.where(inArray(schema.documentChunks.documentId, documentIds));
|
|
1181
|
+
}
|
|
1182
|
+
return acl;
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
type KnowledgeDocumentObservationMetadata = {
|
|
1187
|
+
title: string;
|
|
1188
|
+
sourceUri: string;
|
|
1189
|
+
sourceVersion: string;
|
|
1190
|
+
sourceUpdatedAt: Date | null;
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
async function lockKnowledgeSourceSyncObservationFloor(
|
|
1194
|
+
scopedDb: Database,
|
|
1195
|
+
input: {
|
|
1196
|
+
sourceId: string;
|
|
1197
|
+
externalObjectId: string;
|
|
1198
|
+
fence: KnowledgeSourceSyncVersionObservationFence;
|
|
1199
|
+
},
|
|
1200
|
+
): Promise<void> {
|
|
1201
|
+
const [observation] = await scopedDb
|
|
1202
|
+
.select({
|
|
1203
|
+
scheduledTaskRunId: schema.knowledgeSourceSyncObjectObservations.scheduledTaskRunId,
|
|
1204
|
+
scanGeneration: schema.knowledgeSourceSyncObjectObservations.scanGeneration,
|
|
1205
|
+
providerRevision: schema.knowledgeSourceSyncObjectObservations.providerRevision,
|
|
1206
|
+
metadataHash: schema.knowledgeSourceSyncObjectObservations.metadataHash,
|
|
1207
|
+
})
|
|
1208
|
+
.from(schema.knowledgeSourceSyncObjectObservations)
|
|
1209
|
+
.where(
|
|
1210
|
+
and(
|
|
1211
|
+
eq(schema.knowledgeSourceSyncObjectObservations.sourceId, input.sourceId),
|
|
1212
|
+
eq(schema.knowledgeSourceSyncObjectObservations.externalObjectId, input.externalObjectId),
|
|
1213
|
+
),
|
|
1214
|
+
)
|
|
1215
|
+
.for("share")
|
|
1216
|
+
.limit(1);
|
|
1217
|
+
if (
|
|
1218
|
+
!observation ||
|
|
1219
|
+
observation.scheduledTaskRunId !== input.fence.scheduledTaskRunId ||
|
|
1220
|
+
observation.scanGeneration !== input.fence.scanGeneration ||
|
|
1221
|
+
observation.providerRevision !== input.fence.providerRevision ||
|
|
1222
|
+
observation.metadataHash !== input.fence.metadataHash
|
|
1223
|
+
) {
|
|
1224
|
+
throw new KnowledgeSourceSyncObservationFenceError(
|
|
1225
|
+
"Knowledge source observation floor changed before document mutation",
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
async function lockActiveKnowledgeDocumentAuthority(
|
|
1231
|
+
scopedDb: Database,
|
|
1232
|
+
input: {
|
|
1233
|
+
accountId: string;
|
|
1234
|
+
sourceId: string;
|
|
1235
|
+
expectedSourceLifecycleGeneration: number;
|
|
1236
|
+
objectId: string;
|
|
1237
|
+
expectedObjectLifecycleGeneration: number;
|
|
1238
|
+
},
|
|
1239
|
+
): Promise<{ currentVersionId: string | null; externalObjectId: string }> {
|
|
1240
|
+
await scopedDb.execute(sql`
|
|
1241
|
+
SELECT knowledge_source_sync_lock_authority(
|
|
1242
|
+
${input.accountId}::uuid,
|
|
1243
|
+
${input.sourceId}::uuid,
|
|
1244
|
+
${input.objectId}::uuid
|
|
1245
|
+
)
|
|
1246
|
+
`);
|
|
1247
|
+
const [[source], [object]] = await Promise.all([
|
|
1248
|
+
scopedDb
|
|
1249
|
+
.select({
|
|
1250
|
+
lifecycleState: schema.knowledgeSources.lifecycleState,
|
|
1251
|
+
lifecycleGeneration: schema.knowledgeSources.lifecycleGeneration,
|
|
1252
|
+
})
|
|
1253
|
+
.from(schema.knowledgeSources)
|
|
1254
|
+
.where(eq(schema.knowledgeSources.id, input.sourceId))
|
|
1255
|
+
.limit(1),
|
|
1256
|
+
scopedDb
|
|
1257
|
+
.select({
|
|
1258
|
+
sourceId: schema.knowledgeSourceObjects.sourceId,
|
|
1259
|
+
lifecycleState: schema.knowledgeSourceObjects.lifecycleState,
|
|
1260
|
+
lifecycleGeneration: schema.knowledgeSourceObjects.lifecycleGeneration,
|
|
1261
|
+
currentVersionId: schema.knowledgeSourceObjects.currentVersionId,
|
|
1262
|
+
externalObjectId: schema.knowledgeSourceObjects.externalObjectId,
|
|
1263
|
+
})
|
|
1264
|
+
.from(schema.knowledgeSourceObjects)
|
|
1265
|
+
.where(eq(schema.knowledgeSourceObjects.id, input.objectId))
|
|
1266
|
+
.limit(1),
|
|
1267
|
+
]);
|
|
1268
|
+
if (
|
|
1269
|
+
!source ||
|
|
1270
|
+
!object ||
|
|
1271
|
+
source.lifecycleState !== "active" ||
|
|
1272
|
+
source.lifecycleGeneration !== input.expectedSourceLifecycleGeneration ||
|
|
1273
|
+
object.sourceId !== input.sourceId ||
|
|
1274
|
+
object.lifecycleState !== "active" ||
|
|
1275
|
+
object.lifecycleGeneration !== input.expectedObjectLifecycleGeneration
|
|
1276
|
+
) {
|
|
1277
|
+
throw new ScopedKnowledgeGenerationConflictError(
|
|
1278
|
+
"Knowledge document metadata authority is no longer active",
|
|
1279
|
+
);
|
|
1280
|
+
}
|
|
1281
|
+
return { currentVersionId: object.currentVersionId, externalObjectId: object.externalObjectId };
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
async function convergeKnowledgeDocumentObservationMetadata(
|
|
1285
|
+
scopedDb: Database,
|
|
1286
|
+
input: {
|
|
1287
|
+
accountId: string;
|
|
1288
|
+
workspaceId: string;
|
|
1289
|
+
documentId: string;
|
|
1290
|
+
metadata: KnowledgeDocumentObservationMetadata;
|
|
1291
|
+
},
|
|
1292
|
+
): Promise<void> {
|
|
1293
|
+
const updatedAt = new Date();
|
|
1294
|
+
const chunkProvenanceMetadata = JSON.stringify({
|
|
1295
|
+
documentTitle: input.metadata.title,
|
|
1296
|
+
sourceUri: input.metadata.sourceUri,
|
|
1297
|
+
sourceTitle: input.metadata.title,
|
|
1298
|
+
sourceUpdatedAt: input.metadata.sourceUpdatedAt?.toISOString() ?? null,
|
|
1299
|
+
sourceVersion: input.metadata.sourceVersion,
|
|
1300
|
+
});
|
|
1301
|
+
const [updated] = await scopedDb
|
|
1302
|
+
.update(schema.documents)
|
|
1303
|
+
.set({
|
|
1304
|
+
title: input.metadata.title,
|
|
1305
|
+
sourceUri: input.metadata.sourceUri,
|
|
1306
|
+
sourceTitle: input.metadata.title,
|
|
1307
|
+
sourceVersion: input.metadata.sourceVersion,
|
|
1308
|
+
sourceUpdatedAt: input.metadata.sourceUpdatedAt,
|
|
1309
|
+
updatedAt,
|
|
1310
|
+
})
|
|
1311
|
+
.where(
|
|
1312
|
+
and(
|
|
1313
|
+
eq(schema.documents.accountId, input.accountId),
|
|
1314
|
+
eq(schema.documents.workspaceId, input.workspaceId),
|
|
1315
|
+
eq(schema.documents.id, input.documentId),
|
|
1316
|
+
),
|
|
1317
|
+
)
|
|
1318
|
+
.returning({ id: schema.documents.id });
|
|
1319
|
+
if (!updated) throw new ScopedKnowledgeNotFoundError("Knowledge document was not found");
|
|
1320
|
+
|
|
1321
|
+
await scopedDb
|
|
1322
|
+
.update(schema.documentChunks)
|
|
1323
|
+
.set({
|
|
1324
|
+
metadata: sql<Record<string, unknown>>`${schema.documentChunks.metadata} ||
|
|
1325
|
+
${chunkProvenanceMetadata}::jsonb`,
|
|
1326
|
+
})
|
|
1327
|
+
.where(
|
|
1328
|
+
and(
|
|
1329
|
+
eq(schema.documentChunks.accountId, input.accountId),
|
|
1330
|
+
eq(schema.documentChunks.workspaceId, input.workspaceId),
|
|
1331
|
+
eq(schema.documentChunks.documentId, input.documentId),
|
|
1332
|
+
),
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
export async function updateKnowledgeSourceDocumentObservationMetadata(
|
|
1337
|
+
db: Database,
|
|
1338
|
+
input: {
|
|
1339
|
+
accountId: string;
|
|
1340
|
+
workspaceId: string;
|
|
1341
|
+
initiatingSubjectId: string;
|
|
1342
|
+
sourceId: string;
|
|
1343
|
+
expectedSourceLifecycleGeneration: number;
|
|
1344
|
+
objectId: string;
|
|
1345
|
+
expectedObjectLifecycleGeneration: number;
|
|
1346
|
+
versionId: string;
|
|
1347
|
+
documentId: string;
|
|
1348
|
+
title: string;
|
|
1349
|
+
sourceUri: string;
|
|
1350
|
+
sourceVersion: string;
|
|
1351
|
+
sourceUpdatedAt: string | null;
|
|
1352
|
+
syncObservation?: KnowledgeSourceSyncVersionObservationFence;
|
|
1353
|
+
},
|
|
1354
|
+
): Promise<void> {
|
|
1355
|
+
const metadata: KnowledgeDocumentObservationMetadata = {
|
|
1356
|
+
title: boundedText(input.title, "title", 1000),
|
|
1357
|
+
sourceUri: boundedText(input.sourceUri, "sourceUri", 4096),
|
|
1358
|
+
sourceVersion: boundedText(input.sourceVersion, "sourceVersion", 1024),
|
|
1359
|
+
sourceUpdatedAt: input.sourceUpdatedAt ? new Date(input.sourceUpdatedAt) : null,
|
|
1360
|
+
};
|
|
1361
|
+
await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
1362
|
+
if (input.syncObservation) {
|
|
1363
|
+
const [observationObject] = await scopedDb
|
|
1364
|
+
.select({
|
|
1365
|
+
sourceId: schema.knowledgeSourceObjects.sourceId,
|
|
1366
|
+
externalObjectId: schema.knowledgeSourceObjects.externalObjectId,
|
|
1367
|
+
})
|
|
1368
|
+
.from(schema.knowledgeSourceObjects)
|
|
1369
|
+
.where(eq(schema.knowledgeSourceObjects.id, input.objectId))
|
|
1370
|
+
.limit(1);
|
|
1371
|
+
if (!observationObject || observationObject.sourceId !== input.sourceId) {
|
|
1372
|
+
throw new KnowledgeSourceSyncObservationFenceError(
|
|
1373
|
+
"Knowledge source observation object is no longer current",
|
|
1374
|
+
);
|
|
1375
|
+
}
|
|
1376
|
+
await lockKnowledgeSourceSyncObservationFloor(scopedDb, {
|
|
1377
|
+
sourceId: input.sourceId,
|
|
1378
|
+
externalObjectId: observationObject.externalObjectId,
|
|
1379
|
+
fence: input.syncObservation,
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
const object = await lockActiveKnowledgeDocumentAuthority(scopedDb, input);
|
|
1383
|
+
const [version] = await scopedDb
|
|
1384
|
+
.select()
|
|
1385
|
+
.from(schema.knowledgeDocumentVersions)
|
|
1386
|
+
.where(eq(schema.knowledgeDocumentVersions.id, input.versionId))
|
|
1387
|
+
.limit(1);
|
|
1388
|
+
if (
|
|
1389
|
+
!object ||
|
|
1390
|
+
!version ||
|
|
1391
|
+
object.currentVersionId !== input.versionId ||
|
|
1392
|
+
version.sourceId !== input.sourceId ||
|
|
1393
|
+
version.objectId !== input.objectId ||
|
|
1394
|
+
version.documentId !== input.documentId
|
|
1395
|
+
) {
|
|
1396
|
+
throw new ScopedKnowledgeGenerationConflictError(
|
|
1397
|
+
"Knowledge document metadata observation is no longer current",
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
await convergeKnowledgeDocumentObservationMetadata(scopedDb, {
|
|
1401
|
+
accountId: input.accountId,
|
|
1402
|
+
workspaceId: input.workspaceId,
|
|
1403
|
+
documentId: input.documentId,
|
|
1404
|
+
metadata,
|
|
1405
|
+
});
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
|
|
928
1409
|
export async function beginKnowledgeSyncRun(
|
|
929
1410
|
db: Database,
|
|
930
1411
|
input: Omit<KnowledgeWriteContext, "scope"> & {
|
|
@@ -1026,6 +1507,32 @@ export async function beginKnowledgeSyncRun(
|
|
|
1026
1507
|
);
|
|
1027
1508
|
}
|
|
1028
1509
|
|
|
1510
|
+
export async function getKnowledgeSyncRunForSyncAuthority(
|
|
1511
|
+
db: Database,
|
|
1512
|
+
input: {
|
|
1513
|
+
accountId: string;
|
|
1514
|
+
workspaceId: string;
|
|
1515
|
+
sourceId: string;
|
|
1516
|
+
operationId: string;
|
|
1517
|
+
initiatingSubjectId: string;
|
|
1518
|
+
},
|
|
1519
|
+
): Promise<KnowledgeSyncRunRecord | null> {
|
|
1520
|
+
return await withKnowledgeReadRls(db, { ...input, surface: "human" }, async (scopedDb) => {
|
|
1521
|
+
const [row] = await scopedDb
|
|
1522
|
+
.select()
|
|
1523
|
+
.from(schema.knowledgeSyncRuns)
|
|
1524
|
+
.where(
|
|
1525
|
+
and(
|
|
1526
|
+
eq(schema.knowledgeSyncRuns.accountId, input.accountId),
|
|
1527
|
+
eq(schema.knowledgeSyncRuns.sourceId, input.sourceId),
|
|
1528
|
+
eq(schema.knowledgeSyncRuns.operationId, input.operationId),
|
|
1529
|
+
),
|
|
1530
|
+
)
|
|
1531
|
+
.limit(1);
|
|
1532
|
+
return row ? syncFromRow(row) : null;
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1029
1536
|
export async function completeKnowledgeSyncRun(
|
|
1030
1537
|
db: Database,
|
|
1031
1538
|
input: {
|
|
@@ -1066,7 +1573,7 @@ export async function completeKnowledgeSyncRun(
|
|
|
1066
1573
|
${input.runId}::uuid,
|
|
1067
1574
|
${input.state},
|
|
1068
1575
|
${input.state === "succeeded" ? outputCursor : null},
|
|
1069
|
-
${input.watermark
|
|
1576
|
+
${input.watermark ?? null}::timestamptz,
|
|
1070
1577
|
${JSON.stringify(metadata)}::jsonb,
|
|
1071
1578
|
${input.state === "failed" ? errorCode : null},
|
|
1072
1579
|
${completionHash},
|
|
@@ -1251,6 +1758,7 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1251
1758
|
db: Database,
|
|
1252
1759
|
input: Omit<KnowledgeWriteContext, "scope"> & {
|
|
1253
1760
|
objectId: string;
|
|
1761
|
+
expectedSourceLifecycleGeneration: number;
|
|
1254
1762
|
expectedObjectLifecycleGeneration: number;
|
|
1255
1763
|
expectedVersionGeneration: number;
|
|
1256
1764
|
externalVersionId: string;
|
|
@@ -1265,6 +1773,13 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1265
1773
|
documentId?: string | null;
|
|
1266
1774
|
fileId?: string | null;
|
|
1267
1775
|
locationMetadata?: Record<string, unknown> | undefined;
|
|
1776
|
+
documentObservationMetadata?: {
|
|
1777
|
+
title: string;
|
|
1778
|
+
sourceUri: string;
|
|
1779
|
+
sourceVersion: string;
|
|
1780
|
+
sourceUpdatedAt: string | null;
|
|
1781
|
+
};
|
|
1782
|
+
syncObservation?: KnowledgeSourceSyncVersionObservationFence;
|
|
1268
1783
|
reasonCode: string;
|
|
1269
1784
|
},
|
|
1270
1785
|
): Promise<KnowledgeDocumentVersionRecord> {
|
|
@@ -1274,6 +1789,18 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1274
1789
|
const sourceCursor =
|
|
1275
1790
|
input.sourceCursor == null ? null : boundedText(input.sourceCursor, "sourceCursor", 4096);
|
|
1276
1791
|
const reasonCode = normalizedStableKey(input.reasonCode, "reasonCode", 128);
|
|
1792
|
+
const documentObservationMetadata = input.documentObservationMetadata
|
|
1793
|
+
? {
|
|
1794
|
+
title: boundedText(input.documentObservationMetadata.title, "title", 1000),
|
|
1795
|
+
sourceUri: boundedText(input.documentObservationMetadata.sourceUri, "sourceUri", 4096),
|
|
1796
|
+
sourceVersion: boundedText(
|
|
1797
|
+
input.documentObservationMetadata.sourceVersion,
|
|
1798
|
+
"sourceVersion",
|
|
1799
|
+
1024,
|
|
1800
|
+
),
|
|
1801
|
+
sourceUpdatedAt: input.documentObservationMetadata.sourceUpdatedAt,
|
|
1802
|
+
}
|
|
1803
|
+
: null;
|
|
1277
1804
|
const placeholderScope: ScopedKnowledgeScope = {
|
|
1278
1805
|
kind: "workspace",
|
|
1279
1806
|
workspaceId: input.workspaceId,
|
|
@@ -1295,6 +1822,7 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1295
1822
|
validateScope(objectScope, input.workspaceId, input.actor.initiatingHumanSubjectId);
|
|
1296
1823
|
const inputHash = scopedKnowledgeInputHash({
|
|
1297
1824
|
objectId: input.objectId,
|
|
1825
|
+
expectedSourceLifecycleGeneration: input.expectedSourceLifecycleGeneration,
|
|
1298
1826
|
expectedObjectLifecycleGeneration: input.expectedObjectLifecycleGeneration,
|
|
1299
1827
|
expectedVersionGeneration: input.expectedVersionGeneration,
|
|
1300
1828
|
externalVersionId,
|
|
@@ -1309,9 +1837,51 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1309
1837
|
documentId: input.documentId ?? null,
|
|
1310
1838
|
fileId: input.fileId ?? null,
|
|
1311
1839
|
locationMetadata: input.locationMetadata ?? {},
|
|
1840
|
+
documentObservationMetadata,
|
|
1841
|
+
syncObservation: input.syncObservation ?? null,
|
|
1312
1842
|
reasonCode,
|
|
1313
1843
|
actor: input.actor,
|
|
1314
1844
|
});
|
|
1845
|
+
if (input.syncObservation) {
|
|
1846
|
+
await lockKnowledgeSourceSyncObservationFloor(scopedDb, {
|
|
1847
|
+
sourceId: object.sourceId,
|
|
1848
|
+
externalObjectId: object.externalObjectId,
|
|
1849
|
+
fence: input.syncObservation,
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
const convergeDocumentObservation = async (version: VersionRow): Promise<void> => {
|
|
1853
|
+
if (!documentObservationMetadata) return;
|
|
1854
|
+
if (!version.documentId || version.documentId !== (input.documentId ?? null)) {
|
|
1855
|
+
throw new ScopedKnowledgeConflictError(
|
|
1856
|
+
"Knowledge document observation metadata has no matching document",
|
|
1857
|
+
);
|
|
1858
|
+
}
|
|
1859
|
+
const liveObject = await lockActiveKnowledgeDocumentAuthority(scopedDb, {
|
|
1860
|
+
accountId: input.accountId,
|
|
1861
|
+
sourceId: object.sourceId,
|
|
1862
|
+
expectedSourceLifecycleGeneration: input.expectedSourceLifecycleGeneration,
|
|
1863
|
+
objectId: input.objectId,
|
|
1864
|
+
expectedObjectLifecycleGeneration: input.expectedObjectLifecycleGeneration,
|
|
1865
|
+
});
|
|
1866
|
+
if (version.sourceId !== object.sourceId || liveObject.currentVersionId !== version.id) {
|
|
1867
|
+
throw new ScopedKnowledgeGenerationConflictError(
|
|
1868
|
+
"Knowledge document metadata observation is no longer current",
|
|
1869
|
+
);
|
|
1870
|
+
}
|
|
1871
|
+
await convergeKnowledgeDocumentObservationMetadata(scopedDb, {
|
|
1872
|
+
accountId: input.accountId,
|
|
1873
|
+
workspaceId: input.workspaceId,
|
|
1874
|
+
documentId: version.documentId,
|
|
1875
|
+
metadata: {
|
|
1876
|
+
title: documentObservationMetadata.title,
|
|
1877
|
+
sourceUri: documentObservationMetadata.sourceUri,
|
|
1878
|
+
sourceVersion: documentObservationMetadata.sourceVersion,
|
|
1879
|
+
sourceUpdatedAt: documentObservationMetadata.sourceUpdatedAt
|
|
1880
|
+
? new Date(documentObservationMetadata.sourceUpdatedAt)
|
|
1881
|
+
: null,
|
|
1882
|
+
},
|
|
1883
|
+
});
|
|
1884
|
+
};
|
|
1315
1885
|
const receiptResultId = await lockConvergentKnowledgeOperation(scopedDb, {
|
|
1316
1886
|
accountId: input.accountId,
|
|
1317
1887
|
operationKind: "document_version",
|
|
@@ -1330,6 +1900,7 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1330
1900
|
"Knowledge document-version operation receipt has no visible result",
|
|
1331
1901
|
);
|
|
1332
1902
|
}
|
|
1903
|
+
await convergeDocumentObservation(replayed);
|
|
1333
1904
|
return versionFromRow(replayed);
|
|
1334
1905
|
}
|
|
1335
1906
|
const existingRows = await scopedDb
|
|
@@ -1340,7 +1911,6 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1340
1911
|
eq(schema.knowledgeDocumentVersions.objectId, input.objectId),
|
|
1341
1912
|
sql`(
|
|
1342
1913
|
${schema.knowledgeDocumentVersions.operationId} = ${input.operationId}
|
|
1343
|
-
OR ${schema.knowledgeDocumentVersions.externalVersionId} = ${externalVersionId}
|
|
1344
1914
|
OR ${schema.knowledgeDocumentVersions.ingestionKey} = ${ingestionKey}
|
|
1345
1915
|
)`,
|
|
1346
1916
|
),
|
|
@@ -1366,6 +1936,7 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1366
1936
|
resultId: existing.id,
|
|
1367
1937
|
actor: input.actor,
|
|
1368
1938
|
});
|
|
1939
|
+
await convergeDocumentObservation(existing);
|
|
1369
1940
|
return versionFromRow(existing);
|
|
1370
1941
|
}
|
|
1371
1942
|
const [source, acl] = await Promise.all([
|
|
@@ -1395,6 +1966,7 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1395
1966
|
object.lifecycleGeneration !== input.expectedObjectLifecycleGeneration ||
|
|
1396
1967
|
object.versionGeneration !== input.expectedVersionGeneration ||
|
|
1397
1968
|
sourceRow.lifecycleState !== "active" ||
|
|
1969
|
+
sourceRow.lifecycleGeneration !== input.expectedSourceLifecycleGeneration ||
|
|
1398
1970
|
sourceRow.currentAclGeneration !== input.aclGeneration
|
|
1399
1971
|
) {
|
|
1400
1972
|
throw new ScopedKnowledgeGenerationConflictError(
|
|
@@ -1439,7 +2011,6 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1439
2011
|
eq(schema.knowledgeDocumentVersions.objectId, input.objectId),
|
|
1440
2012
|
sql`(
|
|
1441
2013
|
${schema.knowledgeDocumentVersions.operationId} = ${input.operationId}
|
|
1442
|
-
OR ${schema.knowledgeDocumentVersions.externalVersionId} = ${externalVersionId}
|
|
1443
2014
|
OR ${schema.knowledgeDocumentVersions.ingestionKey} = ${ingestionKey}
|
|
1444
2015
|
)`,
|
|
1445
2016
|
),
|
|
@@ -1456,6 +2027,7 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1456
2027
|
resultId: converged.id,
|
|
1457
2028
|
actor: input.actor,
|
|
1458
2029
|
});
|
|
2030
|
+
await convergeDocumentObservation(converged);
|
|
1459
2031
|
return versionFromRow(converged);
|
|
1460
2032
|
}
|
|
1461
2033
|
throw new ScopedKnowledgeGenerationConflictError(
|
|
@@ -1477,6 +2049,44 @@ export async function appendKnowledgeDocumentVersion(
|
|
|
1477
2049
|
${input.actor.initiatingHumanSubjectId}
|
|
1478
2050
|
)
|
|
1479
2051
|
`);
|
|
2052
|
+
await convergeDocumentObservation(created);
|
|
2053
|
+
if (object.currentVersionId) {
|
|
2054
|
+
const [previousVersion] = await scopedDb
|
|
2055
|
+
.select({ documentId: schema.knowledgeDocumentVersions.documentId })
|
|
2056
|
+
.from(schema.knowledgeDocumentVersions)
|
|
2057
|
+
.where(eq(schema.knowledgeDocumentVersions.id, object.currentVersionId))
|
|
2058
|
+
.limit(1);
|
|
2059
|
+
if (previousVersion?.documentId) {
|
|
2060
|
+
const retiredAt = new Date();
|
|
2061
|
+
await scopedDb
|
|
2062
|
+
.update(schema.knowledgeSourceSyncIndexObligations)
|
|
2063
|
+
.set({
|
|
2064
|
+
status: "invalidated",
|
|
2065
|
+
aclEligibility: "denied",
|
|
2066
|
+
failureCode: "superseded_source_version",
|
|
2067
|
+
updatedAt: retiredAt,
|
|
2068
|
+
})
|
|
2069
|
+
.where(
|
|
2070
|
+
eq(
|
|
2071
|
+
schema.knowledgeSourceSyncIndexObligations.knowledgeDocumentVersionId,
|
|
2072
|
+
object.currentVersionId,
|
|
2073
|
+
),
|
|
2074
|
+
);
|
|
2075
|
+
await scopedDb
|
|
2076
|
+
.update(schema.documents)
|
|
2077
|
+
.set({ agentAccess: false, updatedAt: retiredAt })
|
|
2078
|
+
.where(eq(schema.documents.id, previousVersion.documentId));
|
|
2079
|
+
if (previousVersion.documentId !== created.documentId) {
|
|
2080
|
+
await scopedDb
|
|
2081
|
+
.update(schema.documents)
|
|
2082
|
+
.set({ chunkCount: 0, updatedAt: retiredAt })
|
|
2083
|
+
.where(eq(schema.documents.id, previousVersion.documentId));
|
|
2084
|
+
await scopedDb
|
|
2085
|
+
.delete(schema.documentChunks)
|
|
2086
|
+
.where(eq(schema.documentChunks.documentId, previousVersion.documentId));
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
1480
2090
|
await recordConvergentKnowledgeOperation(scopedDb, {
|
|
1481
2091
|
accountId: input.accountId,
|
|
1482
2092
|
scope: objectScope,
|
|
@@ -1552,6 +2162,48 @@ export async function recordKnowledgeLifecycleEvent(
|
|
|
1552
2162
|
}>;
|
|
1553
2163
|
const row = rows[0];
|
|
1554
2164
|
if (!row) throw new Error("Knowledge lifecycle transition returned no row");
|
|
2165
|
+
if (
|
|
2166
|
+
(input.targetKind === "source" || input.targetKind === "object") &&
|
|
2167
|
+
input.eventType !== "restored"
|
|
2168
|
+
) {
|
|
2169
|
+
const retiredAt = new Date();
|
|
2170
|
+
const versions = await scopedDb
|
|
2171
|
+
.select({ documentId: schema.knowledgeDocumentVersions.documentId })
|
|
2172
|
+
.from(schema.knowledgeDocumentVersions)
|
|
2173
|
+
.where(
|
|
2174
|
+
input.targetKind === "source"
|
|
2175
|
+
? eq(schema.knowledgeDocumentVersions.sourceId, input.targetId)
|
|
2176
|
+
: eq(schema.knowledgeDocumentVersions.objectId, input.targetId),
|
|
2177
|
+
);
|
|
2178
|
+
const documentIds = versions.flatMap((version) =>
|
|
2179
|
+
version.documentId ? [version.documentId] : [],
|
|
2180
|
+
);
|
|
2181
|
+
await scopedDb
|
|
2182
|
+
.update(schema.knowledgeSourceSyncIndexObligations)
|
|
2183
|
+
.set({
|
|
2184
|
+
status: "invalidated",
|
|
2185
|
+
aclEligibility: "denied",
|
|
2186
|
+
failureCode: `${input.targetKind}_${input.eventType}`,
|
|
2187
|
+
updatedAt: retiredAt,
|
|
2188
|
+
})
|
|
2189
|
+
.where(
|
|
2190
|
+
input.targetKind === "source"
|
|
2191
|
+
? eq(schema.knowledgeSourceSyncIndexObligations.sourceId, input.targetId)
|
|
2192
|
+
: eq(
|
|
2193
|
+
schema.knowledgeSourceSyncIndexObligations.knowledgeSourceObjectId,
|
|
2194
|
+
input.targetId,
|
|
2195
|
+
),
|
|
2196
|
+
);
|
|
2197
|
+
if (documentIds.length > 0) {
|
|
2198
|
+
await scopedDb
|
|
2199
|
+
.update(schema.documents)
|
|
2200
|
+
.set({ agentAccess: false, chunkCount: 0, updatedAt: retiredAt })
|
|
2201
|
+
.where(inArray(schema.documents.id, documentIds));
|
|
2202
|
+
await scopedDb
|
|
2203
|
+
.delete(schema.documentChunks)
|
|
2204
|
+
.where(inArray(schema.documentChunks.documentId, documentIds));
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
1555
2207
|
return {
|
|
1556
2208
|
targetId: row.target_id,
|
|
1557
2209
|
lifecycleState: row.lifecycle_state,
|