weave-typescript 0.28.0 → 0.30.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.
@@ -1,13 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.upsertFacetConfigQuery = exports.listActiveFacetConfigsQuery = exports.listFacetConfigsQuery = exports.syncOrganizationIngestionReasoningDefaultsQuery = exports.upsertOrganizationIngestionSettingsQuery = exports.getOrganizationIngestionSettingsQuery = exports.ensureOrganizationIngestionSettingsQuery = exports.listEntitiesByThreadQuery = exports.upsertEntityRelationshipQuery = exports.upsertThreadEntityQuery = exports.upsertEntityQuery = exports.listThreadActivityByThreadQuery = exports.createThreadActivityQuery = exports.listThreadReconciliationByPendingThreadQuery = exports.upsertThreadReconciliationQuery = exports.deleteThreadReconciliationByPendingThreadQuery = exports.getIngestionRunThreadCountsQuery = exports.listThreadsByIDsQuery = exports.listThreadsBySupersedesQuery = exports.markThreadsSupersededQuery = exports.bulkRejectThreadsQuery = exports.rejectThreadQuery = exports.bulkApproveThreadsQuery = exports.approveThreadQuery = exports.editPendingThreadQuery = exports.updateThreadClassificationQuery = exports.promoteThreadNextEmbeddingsByOrganizationQuery = exports.setThreadNextEmbeddingQuery = exports.updateThreadEmbeddingQuery = exports.listPendingThreadsByOrganizationQuery = exports.listPendingThreadsByRunQuery = exports.listThreadsByIngestionRunQuery = exports.getThreadByOrganizationAndIDQuery = exports.createThreadQuery = exports.listDocumentTagsByDocumentIDQuery = exports.createDocumentTagQuery = exports.deleteDocumentTagsByDocumentIDQuery = exports.listIngestionHistoryQuery = exports.listIngestionRunsByDocumentQuery = exports.listIngestionRunsByOrganizationQuery = exports.updateIngestionRunStateQuery = exports.getIngestionRunByOrganizationAndIDQuery = exports.createIngestionRunQuery = exports.getDatabaseConfigQuery = exports.listDocumentsByOrganizationQuery = exports.setDocumentStatusQuery = exports.setDocumentParseResultQuery = exports.getDocumentByOrganizationAndFingerprintQuery = exports.getDocumentByOrganizationAndIDQuery = exports.createDocumentQuery = void 0;
4
- exports.deactivateFacetConfigQuery = void 0;
3
+ exports.listEntitiesByThreadQuery = exports.upsertEntityRelationshipQuery = exports.upsertThreadEntityQuery = exports.upsertEntityQuery = exports.listThreadActivityByThreadQuery = exports.createThreadActivityQuery = exports.listThreadReconciliationByPendingThreadQuery = exports.upsertThreadReconciliationQuery = exports.deleteThreadReconciliationByPendingThreadQuery = exports.getIngestionRunThreadCountsQuery = exports.listThreadsByIDsQuery = exports.listThreadsBySupersedesQuery = exports.markThreadsSupersededQuery = exports.bulkRejectThreadsQuery = exports.rejectThreadQuery = exports.bulkApproveThreadsQuery = exports.approveThreadQuery = exports.deleteDocumentThreadByOrganizationAndIDQuery = exports.editDocumentThreadQuery = exports.editPendingThreadQuery = exports.updateThreadClassificationQuery = exports.promoteThreadNextEmbeddingsByOrganizationQuery = exports.setThreadNextEmbeddingQuery = exports.updateThreadEmbeddingQuery = exports.listPendingThreadsByOrganizationQuery = exports.listPendingThreadsByRunQuery = exports.listThreadsByDocumentQuery = exports.listThreadsByIngestionRunQuery = exports.getThreadByOrganizationAndIDQuery = exports.createThreadQuery = exports.deleteDocumentByOrganizationAndIDQuery = exports.listDocumentTagsByDocumentIDQuery = exports.createDocumentTagQuery = exports.deleteDocumentTagByDocumentIDAndTagQuery = exports.deleteDocumentTagsByDocumentIDQuery = exports.listIngestionHistoryQuery = exports.listIngestionRunsByDocumentQuery = exports.listIngestionRunsByOrganizationQuery = exports.updateIngestionRunStateQuery = exports.getIngestionRunByOrganizationAndIDQuery = exports.createIngestionRunQuery = exports.getDatabaseConfigQuery = exports.getAccessibleDocumentSummaryQuery = exports.listAccessibleDocumentSummariesQuery = exports.listDocumentsByOrganizationQuery = exports.setDocumentStatusQuery = exports.setDocumentParseResultQuery = exports.getDocumentByOrganizationAndFingerprintQuery = exports.getDocumentByOrganizationAndIDQuery = exports.createDocumentQuery = void 0;
4
+ exports.deactivateFacetConfigQuery = exports.upsertFacetConfigQuery = exports.listActiveFacetConfigsQuery = exports.listFacetConfigsQuery = exports.syncOrganizationIngestionReasoningDefaultsQuery = exports.upsertOrganizationIngestionSettingsQuery = exports.getOrganizationIngestionSettingsQuery = exports.ensureOrganizationIngestionSettingsQuery = void 0;
5
5
  exports.createDocument = createDocument;
6
6
  exports.getDocumentByOrganizationAndID = getDocumentByOrganizationAndID;
7
7
  exports.getDocumentByOrganizationAndFingerprint = getDocumentByOrganizationAndFingerprint;
8
8
  exports.setDocumentParseResult = setDocumentParseResult;
9
9
  exports.setDocumentStatus = setDocumentStatus;
10
10
  exports.listDocumentsByOrganization = listDocumentsByOrganization;
11
+ exports.listAccessibleDocumentSummaries = listAccessibleDocumentSummaries;
12
+ exports.getAccessibleDocumentSummary = getAccessibleDocumentSummary;
11
13
  exports.getDatabaseConfig = getDatabaseConfig;
12
14
  exports.createIngestionRun = createIngestionRun;
13
15
  exports.getIngestionRunByOrganizationAndID = getIngestionRunByOrganizationAndID;
@@ -21,12 +23,14 @@ exports.listDocumentTagsByDocumentID = listDocumentTagsByDocumentID;
21
23
  exports.createThread = createThread;
22
24
  exports.getThreadByOrganizationAndID = getThreadByOrganizationAndID;
23
25
  exports.listThreadsByIngestionRun = listThreadsByIngestionRun;
26
+ exports.listThreadsByDocument = listThreadsByDocument;
24
27
  exports.listPendingThreadsByRun = listPendingThreadsByRun;
25
28
  exports.listPendingThreadsByOrganization = listPendingThreadsByOrganization;
26
29
  exports.updateThreadEmbedding = updateThreadEmbedding;
27
30
  exports.setThreadNextEmbedding = setThreadNextEmbedding;
28
31
  exports.updateThreadClassification = updateThreadClassification;
29
32
  exports.editPendingThread = editPendingThread;
33
+ exports.editDocumentThread = editDocumentThread;
30
34
  exports.approveThread = approveThread;
31
35
  exports.bulkApproveThreads = bulkApproveThreads;
32
36
  exports.rejectThread = rejectThread;
@@ -381,6 +385,245 @@ async function listDocumentsByOrganization(client, args) {
381
385
  };
382
386
  });
383
387
  }
388
+ exports.listAccessibleDocumentSummariesQuery = `-- name: ListAccessibleDocumentSummaries :many
389
+ WITH latest_runs AS (
390
+ SELECT DISTINCT ON (r.document_id)
391
+ r.document_id,
392
+ r.id AS latest_ingestion_run_id,
393
+ r.status AS latest_ingestion_status
394
+ FROM weave.ingestion_runs r
395
+ WHERE r.organization_id = $1
396
+ ORDER BY r.document_id, r.started_at DESC
397
+ ),
398
+ thread_counts AS (
399
+ SELECT
400
+ t.document_id,
401
+ COUNT(*)::int AS thread_count,
402
+ COUNT(*) FILTER (
403
+ WHERE t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_PENDING'
404
+ )::int AS pending_count,
405
+ COUNT(*) FILTER (
406
+ WHERE t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_APPROVED'
407
+ )::int AS approved_count,
408
+ COUNT(*) FILTER (
409
+ WHERE t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_REJECTED'
410
+ )::int AS rejected_count
411
+ FROM weave.threads t
412
+ WHERE t.organization_id = $1
413
+ GROUP BY t.document_id
414
+ ),
415
+ tag_data AS (
416
+ SELECT
417
+ dt.document_id,
418
+ array_agg(dt.tag ORDER BY dt.tag ASC) AS tags,
419
+ array_agg(dt.confidence ORDER BY dt.tag ASC) AS tag_confidences
420
+ FROM weave.document_tags dt
421
+ JOIN weave.documents d ON d.id = dt.document_id
422
+ WHERE d.organization_id = $1
423
+ GROUP BY dt.document_id
424
+ )
425
+ SELECT
426
+ d.id,
427
+ d.organization_id,
428
+ d.filename,
429
+ d.mime_type,
430
+ d.parser_name,
431
+ d.status,
432
+ d.scope,
433
+ d.sensitivity_tags,
434
+ COALESCE(tag_data.tags, '{}'::text[]) AS tags,
435
+ COALESCE(tag_data.tag_confidences, '{}'::real[]) AS tag_confidences,
436
+ d.uploaded_by_user_id,
437
+ d.uploaded_at,
438
+ d.updated_at,
439
+ d.page_count,
440
+ d.char_count,
441
+ d.metadata,
442
+ COALESCE(latest_runs.latest_ingestion_run_id, '00000000-0000-0000-0000-000000000000'::uuid) AS latest_ingestion_run_id,
443
+ COALESCE(latest_runs.latest_ingestion_status, 'INGESTION_RUN_STATUS_UNSPECIFIED') AS latest_ingestion_status,
444
+ COALESCE(thread_counts.thread_count, 0)::int AS thread_count,
445
+ COALESCE(thread_counts.pending_count, 0)::int AS pending_count,
446
+ COALESCE(thread_counts.approved_count, 0)::int AS approved_count,
447
+ COALESCE(thread_counts.rejected_count, 0)::int AS rejected_count
448
+ FROM weave.documents d
449
+ LEFT JOIN latest_runs ON latest_runs.document_id = d.id
450
+ LEFT JOIN thread_counts ON thread_counts.document_id = d.id
451
+ LEFT JOIN tag_data ON tag_data.document_id = d.id
452
+ WHERE d.organization_id = $1
453
+ AND (
454
+ d.scope = 'DOCUMENT_SCOPE_ORG'
455
+ OR (d.scope = 'DOCUMENT_SCOPE_PRIVATE'
456
+ AND d.uploaded_by_user_id = $2)
457
+ OR (d.scope = 'DOCUMENT_SCOPE_RESTRICTED'
458
+ AND EXISTS (
459
+ SELECT 1
460
+ FROM weave.user_sensitivity_clearances c
461
+ WHERE c.organization_id = $1
462
+ AND c.user_id = $2
463
+ AND cardinality(d.sensitivity_tags) = 1
464
+ AND c.sensitivity_tag_slug = d.sensitivity_tags[1]
465
+ ))
466
+ )
467
+ AND (cardinality($3::text[]) = 0 OR d.status = ANY($3::text[]))
468
+ AND (cardinality($4::text[]) = 0 OR latest_runs.latest_ingestion_status = ANY($4::text[]))
469
+ AND (cardinality($5::text[]) = 0 OR d.scope = ANY($5::text[]))
470
+ AND (cardinality($6::text[]) = 0 OR tag_data.tags && $6::text[] OR d.sensitivity_tags && $6::text[])
471
+ AND (cardinality($7::text[]) = 0 OR d.sensitivity_tags && $7::text[])
472
+ AND ($8::timestamptz IS NULL OR d.uploaded_at >= $8::timestamptz)
473
+ AND ($9::timestamptz IS NULL OR d.uploaded_at <= $9::timestamptz)
474
+ ORDER BY d.uploaded_at DESC, d.id DESC
475
+ LIMIT $11 OFFSET $10`;
476
+ async function listAccessibleDocumentSummaries(client, args) {
477
+ const result = await client.query({
478
+ text: exports.listAccessibleDocumentSummariesQuery,
479
+ values: [args.organizationId, args.actingUserId, args.documentStatuses, args.ingestionStatuses, args.scopes, args.tags, args.restrictedTags, args.uploadedAfter, args.uploadedBefore, args.pageOffset, args.pageSize],
480
+ rowMode: "array"
481
+ });
482
+ return result.rows.map(row => {
483
+ return {
484
+ id: row[0],
485
+ organizationId: row[1],
486
+ filename: row[2],
487
+ mimeType: row[3],
488
+ parserName: row[4],
489
+ status: row[5],
490
+ scope: row[6],
491
+ sensitivityTags: row[7],
492
+ tags: row[8],
493
+ tagConfidences: row[9],
494
+ uploadedByUserId: row[10],
495
+ uploadedAt: row[11],
496
+ updatedAt: row[12],
497
+ pageCount: row[13],
498
+ charCount: row[14],
499
+ metadata: row[15],
500
+ latestIngestionRunId: row[16],
501
+ latestIngestionStatus: row[17],
502
+ threadCount: row[18],
503
+ pendingCount: row[19],
504
+ approvedCount: row[20],
505
+ rejectedCount: row[21]
506
+ };
507
+ });
508
+ }
509
+ exports.getAccessibleDocumentSummaryQuery = `-- name: GetAccessibleDocumentSummary :one
510
+ WITH latest_runs AS (
511
+ SELECT DISTINCT ON (r.document_id)
512
+ r.document_id,
513
+ r.id AS latest_ingestion_run_id,
514
+ r.status AS latest_ingestion_status
515
+ FROM weave.ingestion_runs r
516
+ WHERE r.organization_id = $1
517
+ AND r.document_id = $2
518
+ ORDER BY r.document_id, r.started_at DESC
519
+ ),
520
+ thread_counts AS (
521
+ SELECT
522
+ t.document_id,
523
+ COUNT(*)::int AS thread_count,
524
+ COUNT(*) FILTER (
525
+ WHERE t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_PENDING'
526
+ )::int AS pending_count,
527
+ COUNT(*) FILTER (
528
+ WHERE t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_APPROVED'
529
+ )::int AS approved_count,
530
+ COUNT(*) FILTER (
531
+ WHERE t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_REJECTED'
532
+ )::int AS rejected_count
533
+ FROM weave.threads t
534
+ WHERE t.organization_id = $1
535
+ AND t.document_id = $2
536
+ GROUP BY t.document_id
537
+ ),
538
+ tag_data AS (
539
+ SELECT
540
+ dt.document_id,
541
+ array_agg(dt.tag ORDER BY dt.tag ASC) AS tags,
542
+ array_agg(dt.confidence ORDER BY dt.tag ASC) AS tag_confidences
543
+ FROM weave.document_tags dt
544
+ JOIN weave.documents d ON d.id = dt.document_id
545
+ WHERE d.organization_id = $1
546
+ AND dt.document_id = $2
547
+ GROUP BY dt.document_id
548
+ )
549
+ SELECT
550
+ d.id,
551
+ d.organization_id,
552
+ d.filename,
553
+ d.mime_type,
554
+ d.parser_name,
555
+ d.status,
556
+ d.scope,
557
+ d.sensitivity_tags,
558
+ COALESCE(tag_data.tags, '{}'::text[]) AS tags,
559
+ COALESCE(tag_data.tag_confidences, '{}'::real[]) AS tag_confidences,
560
+ d.uploaded_by_user_id,
561
+ d.uploaded_at,
562
+ d.updated_at,
563
+ d.page_count,
564
+ d.char_count,
565
+ d.metadata,
566
+ COALESCE(latest_runs.latest_ingestion_run_id, '00000000-0000-0000-0000-000000000000'::uuid) AS latest_ingestion_run_id,
567
+ COALESCE(latest_runs.latest_ingestion_status, 'INGESTION_RUN_STATUS_UNSPECIFIED') AS latest_ingestion_status,
568
+ COALESCE(thread_counts.thread_count, 0)::int AS thread_count,
569
+ COALESCE(thread_counts.pending_count, 0)::int AS pending_count,
570
+ COALESCE(thread_counts.approved_count, 0)::int AS approved_count,
571
+ COALESCE(thread_counts.rejected_count, 0)::int AS rejected_count
572
+ FROM weave.documents d
573
+ LEFT JOIN latest_runs ON latest_runs.document_id = d.id
574
+ LEFT JOIN thread_counts ON thread_counts.document_id = d.id
575
+ LEFT JOIN tag_data ON tag_data.document_id = d.id
576
+ WHERE d.organization_id = $1
577
+ AND d.id = $2
578
+ AND (
579
+ d.scope = 'DOCUMENT_SCOPE_ORG'
580
+ OR (d.scope = 'DOCUMENT_SCOPE_PRIVATE'
581
+ AND d.uploaded_by_user_id = $3)
582
+ OR (d.scope = 'DOCUMENT_SCOPE_RESTRICTED'
583
+ AND EXISTS (
584
+ SELECT 1
585
+ FROM weave.user_sensitivity_clearances c
586
+ WHERE c.organization_id = $1
587
+ AND c.user_id = $3
588
+ AND cardinality(d.sensitivity_tags) = 1
589
+ AND c.sensitivity_tag_slug = d.sensitivity_tags[1]
590
+ ))
591
+ )`;
592
+ async function getAccessibleDocumentSummary(client, args) {
593
+ const result = await client.query({
594
+ text: exports.getAccessibleDocumentSummaryQuery,
595
+ values: [args.organizationId, args.documentId, args.actingUserId],
596
+ rowMode: "array"
597
+ });
598
+ if (result.rows.length !== 1) {
599
+ return null;
600
+ }
601
+ const row = result.rows[0];
602
+ return {
603
+ id: row[0],
604
+ organizationId: row[1],
605
+ filename: row[2],
606
+ mimeType: row[3],
607
+ parserName: row[4],
608
+ status: row[5],
609
+ scope: row[6],
610
+ sensitivityTags: row[7],
611
+ tags: row[8],
612
+ tagConfidences: row[9],
613
+ uploadedByUserId: row[10],
614
+ uploadedAt: row[11],
615
+ updatedAt: row[12],
616
+ pageCount: row[13],
617
+ charCount: row[14],
618
+ metadata: row[15],
619
+ latestIngestionRunId: row[16],
620
+ latestIngestionStatus: row[17],
621
+ threadCount: row[18],
622
+ pendingCount: row[19],
623
+ approvedCount: row[20],
624
+ rejectedCount: row[21]
625
+ };
626
+ }
384
627
  exports.getDatabaseConfigQuery = `-- name: GetDatabaseConfig :one
385
628
  SELECT
386
629
  id,
@@ -761,6 +1004,13 @@ async function deleteDocumentTagsByDocumentID(client, args) {
761
1004
  rowMode: "array"
762
1005
  });
763
1006
  }
1007
+ exports.deleteDocumentTagByDocumentIDAndTagQuery = `-- name: DeleteDocumentTagByDocumentIDAndTag :execrows
1008
+ DELETE FROM weave.document_tags dt
1009
+ USING weave.documents d
1010
+ WHERE dt.document_id = d.id
1011
+ AND d.organization_id = $1
1012
+ AND dt.document_id = $2
1013
+ AND dt.tag = $3`;
764
1014
  exports.createDocumentTagQuery = `-- name: CreateDocumentTag :one
765
1015
  INSERT INTO weave.document_tags (
766
1016
  document_id,
@@ -809,6 +1059,10 @@ async function listDocumentTagsByDocumentID(client, args) {
809
1059
  };
810
1060
  });
811
1061
  }
1062
+ exports.deleteDocumentByOrganizationAndIDQuery = `-- name: DeleteDocumentByOrganizationAndID :execrows
1063
+ DELETE FROM weave.documents
1064
+ WHERE organization_id = $1
1065
+ AND id = $2`;
812
1066
  exports.createThreadQuery = `-- name: CreateThread :one
813
1067
  INSERT INTO weave.threads (
814
1068
  id,
@@ -1020,6 +1274,68 @@ async function listThreadsByIngestionRun(client, args) {
1020
1274
  };
1021
1275
  });
1022
1276
  }
1277
+ exports.listThreadsByDocumentQuery = `-- name: ListThreadsByDocument :many
1278
+ SELECT
1279
+ t.id,
1280
+ t.organization_id,
1281
+ t.document_id,
1282
+ d.filename AS document_name,
1283
+ t.ingestion_run_id,
1284
+ t.text,
1285
+ t.text_original,
1286
+ t.knowledge_type,
1287
+ t.facet_fields,
1288
+ t.confidence,
1289
+ t.temporal_validity,
1290
+ t.classification,
1291
+ t.retrieval_status,
1292
+ t.source_location,
1293
+ t.superseded_by,
1294
+ t.supersedes,
1295
+ t.cluster_id,
1296
+ t.extracted_at,
1297
+ t.approved_at,
1298
+ t.approved_by_user_id,
1299
+ t.edited,
1300
+ t.metadata
1301
+ FROM weave.threads t
1302
+ JOIN weave.documents d ON d.id = t.document_id
1303
+ WHERE t.organization_id = $1
1304
+ AND t.document_id = $2
1305
+ ORDER BY t.extracted_at ASC, t.id ASC`;
1306
+ async function listThreadsByDocument(client, args) {
1307
+ const result = await client.query({
1308
+ text: exports.listThreadsByDocumentQuery,
1309
+ values: [args.organizationId, args.documentId],
1310
+ rowMode: "array"
1311
+ });
1312
+ return result.rows.map(row => {
1313
+ return {
1314
+ id: row[0],
1315
+ organizationId: row[1],
1316
+ documentId: row[2],
1317
+ documentName: row[3],
1318
+ ingestionRunId: row[4],
1319
+ text: row[5],
1320
+ textOriginal: row[6],
1321
+ knowledgeType: row[7],
1322
+ facetFields: row[8],
1323
+ confidence: row[9],
1324
+ temporalValidity: row[10],
1325
+ classification: row[11],
1326
+ retrievalStatus: row[12],
1327
+ sourceLocation: row[13],
1328
+ supersededBy: row[14],
1329
+ supersedes: row[15],
1330
+ clusterId: row[16],
1331
+ extractedAt: row[17],
1332
+ approvedAt: row[18],
1333
+ approvedByUserId: row[19],
1334
+ edited: row[20],
1335
+ metadata: row[21]
1336
+ };
1337
+ });
1338
+ }
1023
1339
  exports.listPendingThreadsByRunQuery = `-- name: ListPendingThreadsByRun :many
1024
1340
  SELECT
1025
1341
  id,
@@ -1407,6 +1723,111 @@ async function editPendingThread(client, args) {
1407
1723
  metadata: row[20]
1408
1724
  };
1409
1725
  }
1726
+ exports.editDocumentThreadQuery = `-- name: EditDocumentThread :one
1727
+ WITH updated AS (
1728
+ UPDATE weave.threads AS t
1729
+ SET
1730
+ text_original = CASE
1731
+ WHEN t.text_original IS NULL OR t.text_original = '' THEN t.text
1732
+ ELSE t.text_original
1733
+ END,
1734
+ text = $1,
1735
+ source_location = COALESCE($2::jsonb, t.source_location),
1736
+ metadata = t.metadata || COALESCE($3::jsonb, '{}'::jsonb),
1737
+ edited = TRUE
1738
+ WHERE t.id = $4
1739
+ AND t.organization_id = $5
1740
+ AND t.document_id = $6
1741
+ AND t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_PENDING'
1742
+ RETURNING
1743
+ id,
1744
+ organization_id,
1745
+ document_id,
1746
+ ingestion_run_id,
1747
+ text,
1748
+ text_original,
1749
+ knowledge_type,
1750
+ facet_fields,
1751
+ confidence,
1752
+ temporal_validity,
1753
+ classification,
1754
+ retrieval_status,
1755
+ source_location,
1756
+ superseded_by,
1757
+ supersedes,
1758
+ cluster_id,
1759
+ extracted_at,
1760
+ approved_at,
1761
+ approved_by_user_id,
1762
+ edited,
1763
+ metadata
1764
+ )
1765
+ SELECT
1766
+ updated.id,
1767
+ updated.organization_id,
1768
+ updated.document_id,
1769
+ d.filename AS document_name,
1770
+ updated.ingestion_run_id,
1771
+ updated.text,
1772
+ updated.text_original,
1773
+ updated.knowledge_type,
1774
+ updated.facet_fields,
1775
+ updated.confidence,
1776
+ updated.temporal_validity,
1777
+ updated.classification,
1778
+ updated.retrieval_status,
1779
+ updated.source_location,
1780
+ updated.superseded_by,
1781
+ updated.supersedes,
1782
+ updated.cluster_id,
1783
+ updated.extracted_at,
1784
+ updated.approved_at,
1785
+ updated.approved_by_user_id,
1786
+ updated.edited,
1787
+ updated.metadata
1788
+ FROM updated
1789
+ JOIN weave.documents d ON d.id = updated.document_id`;
1790
+ async function editDocumentThread(client, args) {
1791
+ const result = await client.query({
1792
+ text: exports.editDocumentThreadQuery,
1793
+ values: [args.text, args.sourceLocation, args.metadata, args.id, args.organizationId, args.documentId],
1794
+ rowMode: "array"
1795
+ });
1796
+ if (result.rows.length !== 1) {
1797
+ return null;
1798
+ }
1799
+ const row = result.rows[0];
1800
+ return {
1801
+ id: row[0],
1802
+ organizationId: row[1],
1803
+ documentId: row[2],
1804
+ documentName: row[3],
1805
+ ingestionRunId: row[4],
1806
+ text: row[5],
1807
+ textOriginal: row[6],
1808
+ knowledgeType: row[7],
1809
+ facetFields: row[8],
1810
+ confidence: row[9],
1811
+ temporalValidity: row[10],
1812
+ classification: row[11],
1813
+ retrievalStatus: row[12],
1814
+ sourceLocation: row[13],
1815
+ supersededBy: row[14],
1816
+ supersedes: row[15],
1817
+ clusterId: row[16],
1818
+ extractedAt: row[17],
1819
+ approvedAt: row[18],
1820
+ approvedByUserId: row[19],
1821
+ edited: row[20],
1822
+ metadata: row[21]
1823
+ };
1824
+ }
1825
+ exports.deleteDocumentThreadByOrganizationAndIDQuery = `-- name: DeleteDocumentThreadByOrganizationAndID :execrows
1826
+ DELETE FROM weave.threads
1827
+ WHERE organization_id = $1
1828
+ AND document_id = $2
1829
+ AND id = $3
1830
+ AND retrieval_status = 'THREAD_RETRIEVAL_STATUS_PENDING'`;
1410
1831
  exports.approveThreadQuery = `-- name: ApproveThread :one
1411
1832
  UPDATE weave.threads
1412
1833
  SET
@@ -53,6 +53,37 @@ export interface SearchApprovedThreadsSemanticByUserPermissionsRow {
53
53
  conceptCluster: string;
54
54
  }
55
55
  export declare function searchApprovedThreadsSemanticByUserPermissions(client: Client, args: SearchApprovedThreadsSemanticByUserPermissionsArgs): Promise<SearchApprovedThreadsSemanticByUserPermissionsRow[]>;
56
+ export declare const searchAccessibleDocumentsSemanticQuery = "-- name: SearchAccessibleDocumentsSemantic :many\nWITH tag_data AS (\n SELECT\n dt.document_id,\n array_agg(dt.tag ORDER BY dt.tag ASC) AS tags,\n array_agg(dt.confidence ORDER BY dt.tag ASC) AS tag_confidences\n FROM weave.document_tags dt\n JOIN weave.documents d ON d.id = dt.document_id\n WHERE d.organization_id = $4\n GROUP BY dt.document_id\n),\nmatches AS (\n SELECT\n t.id AS thread_id,\n t.text,\n t.classification,\n t.document_id,\n d.filename AS document_name,\n d.mime_type,\n d.scope,\n d.sensitivity_tags,\n d.uploaded_at,\n COALESCE(tag_data.tags, '{}'::text[]) AS tags,\n COALESCE(tag_data.tag_confidences, '{}'::real[]) AS tag_confidences,\n t.source_location,\n t.approved_at,\n CAST(\n 1.0::double precision\n - (t.embedding <=> $5::vector)::double precision\n AS double precision\n ) AS score\n FROM weave.threads t\n JOIN weave.documents d ON d.id = t.document_id\n LEFT JOIN tag_data ON tag_data.document_id = d.id\n WHERE t.organization_id = $4\n AND t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_APPROVED'\n AND t.embedding IS NOT NULL\n AND (\n d.scope = 'DOCUMENT_SCOPE_ORG'\n OR (d.scope = 'DOCUMENT_SCOPE_PRIVATE'\n AND d.uploaded_by_user_id = $6)\n OR (d.scope = 'DOCUMENT_SCOPE_RESTRICTED'\n AND EXISTS (\n SELECT 1\n FROM weave.user_sensitivity_clearances c\n WHERE c.organization_id = $4\n AND c.user_id = $6\n AND cardinality(d.sensitivity_tags) = 1\n AND c.sensitivity_tag_slug = d.sensitivity_tags[1]\n ))\n )\n AND (cardinality($7::text[]) = 0 OR tag_data.tags && $7::text[] OR d.sensitivity_tags && $7::text[])\n AND (cardinality($8::text[]) = 0 OR d.sensitivity_tags && $8::text[])\n AND (cardinality($9::text[]) = 0 OR d.scope = ANY($9::text[]))\n AND ($10::timestamptz IS NULL OR d.uploaded_at >= $10::timestamptz)\n AND ($11::timestamptz IS NULL OR d.uploaded_at <= $11::timestamptz)\n)\nSELECT\n document_id,\n document_name,\n mime_type,\n scope,\n sensitivity_tags,\n tags,\n tag_confidences,\n uploaded_at,\n MAX(score)::double precision AS score,\n COUNT(*)::int AS matched_thread_count,\n (array_agg(thread_id ORDER BY score DESC, approved_at DESC))[1] AS best_thread_id,\n (array_agg(text ORDER BY score DESC, approved_at DESC))[1] AS best_text,\n (array_agg(classification ORDER BY score DESC, approved_at DESC))[1] AS best_classification,\n (array_agg(source_location ORDER BY score DESC, approved_at DESC))[1] AS best_source_location\nFROM matches\nWHERE score >= $1::double precision\nGROUP BY\n document_id,\n document_name,\n mime_type,\n scope,\n sensitivity_tags,\n tags,\n tag_confidences,\n uploaded_at\nORDER BY score DESC, uploaded_at DESC\nLIMIT $3 OFFSET $2";
57
+ export interface SearchAccessibleDocumentsSemanticArgs {
58
+ minSimilarity: number;
59
+ pageOffset: string;
60
+ resultLimit: string;
61
+ organizationId: string;
62
+ queryEmbedding: string;
63
+ actingUserId: string;
64
+ tags: string[];
65
+ restrictedTags: string[];
66
+ scopes: string[];
67
+ uploadedAfter: Date | null;
68
+ uploadedBefore: Date | null;
69
+ }
70
+ export interface SearchAccessibleDocumentsSemanticRow {
71
+ documentId: string;
72
+ documentName: string;
73
+ mimeType: string;
74
+ scope: string;
75
+ sensitivityTags: string[];
76
+ tags: string;
77
+ tagConfidences: string;
78
+ uploadedAt: Date;
79
+ score: number;
80
+ matchedThreadCount: number;
81
+ bestThreadId: string | null;
82
+ bestText: string | null;
83
+ bestClassification: string | null;
84
+ bestSourceLocation: string | null;
85
+ }
86
+ export declare function searchAccessibleDocumentsSemantic(client: Client, args: SearchAccessibleDocumentsSemanticArgs): Promise<SearchAccessibleDocumentsSemanticRow[]>;
56
87
  export declare const searchApprovedThreadsSemanticByKnowledgeTypesQuery = "-- name: SearchApprovedThreadsSemanticByKnowledgeTypes :many\nSELECT\n t.id AS thread_id,\n t.text,\n t.knowledge_type,\n t.facet_fields,\n similarity.score,\n t.classification,\n t.document_id,\n d.filename AS document_name,\n t.source_location,\n t.approved_at,\n t.temporal_validity,\n COALESCE(entity_data.entities, '{}'::text[]) AS entities,\n COALESCE(rs.reinforcement_count, 0) AS reinforcement_count,\n COALESCE(cc.name, '') AS concept_cluster\nFROM weave.threads t\nJOIN weave.documents d ON d.id = t.document_id\nCROSS JOIN LATERAL (\n SELECT CAST(\n 1.0::double precision\n - (t.embedding <=> $1::vector)::double precision\n AS double precision\n ) AS score\n) similarity\nLEFT JOIN weave.thread_reinforcement_scores rs ON rs.thread_id = t.id\nLEFT JOIN weave.concept_clusters cc ON cc.id = t.cluster_id\nLEFT JOIN LATERAL (\n SELECT array_agg(DISTINCT e.canonical ORDER BY e.canonical) AS entities\n FROM weave.thread_entities te\n JOIN weave.entities e ON e.id = te.entity_id\n WHERE te.thread_id = t.id\n) entity_data ON TRUE\nWHERE t.organization_id = $2\n AND t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_APPROVED'\n AND t.embedding IS NOT NULL\n AND t.knowledge_type = ANY($3::text[])\n AND similarity.score >= $4::double precision\nORDER BY score DESC, t.approved_at DESC\nLIMIT $5";
57
88
  export interface SearchApprovedThreadsSemanticByKnowledgeTypesArgs {
58
89
  queryEmbedding: string;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.listApprovedReconcilePoolByOrganizationQuery = exports.deleteSessionRetrievalContextQuery = exports.listSessionRetrievalContextQuery = exports.insertSessionRetrievalContextQuery = exports.searchConceptClusterThreadsBySimilarityAndUserPermissionsQuery = exports.searchConceptClusterThreadsBySimilarityQuery = exports.searchLeafConceptClustersBySimilarityQuery = exports.searchApprovedThreadsByEntitiesAndUserPermissionsQuery = exports.searchApprovedThreadsByEntitiesQuery = exports.searchApprovedThreadsSemanticByKnowledgeTypesAndUserPermissionsQuery = exports.searchApprovedThreadsSemanticByKnowledgeTypesQuery = exports.searchApprovedThreadsSemanticByUserPermissionsQuery = exports.searchApprovedThreadsSemanticQuery = exports.refreshThreadReinforcementScoresQuery = void 0;
3
+ exports.listApprovedReconcilePoolByOrganizationQuery = exports.deleteSessionRetrievalContextQuery = exports.listSessionRetrievalContextQuery = exports.insertSessionRetrievalContextQuery = exports.searchConceptClusterThreadsBySimilarityAndUserPermissionsQuery = exports.searchConceptClusterThreadsBySimilarityQuery = exports.searchLeafConceptClustersBySimilarityQuery = exports.searchApprovedThreadsByEntitiesAndUserPermissionsQuery = exports.searchApprovedThreadsByEntitiesQuery = exports.searchApprovedThreadsSemanticByKnowledgeTypesAndUserPermissionsQuery = exports.searchApprovedThreadsSemanticByKnowledgeTypesQuery = exports.searchAccessibleDocumentsSemanticQuery = exports.searchApprovedThreadsSemanticByUserPermissionsQuery = exports.searchApprovedThreadsSemanticQuery = exports.refreshThreadReinforcementScoresQuery = void 0;
4
4
  exports.refreshThreadReinforcementScores = refreshThreadReinforcementScores;
5
5
  exports.searchApprovedThreadsSemantic = searchApprovedThreadsSemantic;
6
6
  exports.searchApprovedThreadsSemanticByUserPermissions = searchApprovedThreadsSemanticByUserPermissions;
7
+ exports.searchAccessibleDocumentsSemantic = searchAccessibleDocumentsSemantic;
7
8
  exports.searchApprovedThreadsSemanticByKnowledgeTypes = searchApprovedThreadsSemanticByKnowledgeTypes;
8
9
  exports.searchApprovedThreadsSemanticByKnowledgeTypesAndUserPermissions = searchApprovedThreadsSemanticByKnowledgeTypesAndUserPermissions;
9
10
  exports.searchApprovedThreadsByEntities = searchApprovedThreadsByEntities;
@@ -166,6 +167,116 @@ async function searchApprovedThreadsSemanticByUserPermissions(client, args) {
166
167
  };
167
168
  });
168
169
  }
170
+ exports.searchAccessibleDocumentsSemanticQuery = `-- name: SearchAccessibleDocumentsSemantic :many
171
+ WITH tag_data AS (
172
+ SELECT
173
+ dt.document_id,
174
+ array_agg(dt.tag ORDER BY dt.tag ASC) AS tags,
175
+ array_agg(dt.confidence ORDER BY dt.tag ASC) AS tag_confidences
176
+ FROM weave.document_tags dt
177
+ JOIN weave.documents d ON d.id = dt.document_id
178
+ WHERE d.organization_id = $4
179
+ GROUP BY dt.document_id
180
+ ),
181
+ matches AS (
182
+ SELECT
183
+ t.id AS thread_id,
184
+ t.text,
185
+ t.classification,
186
+ t.document_id,
187
+ d.filename AS document_name,
188
+ d.mime_type,
189
+ d.scope,
190
+ d.sensitivity_tags,
191
+ d.uploaded_at,
192
+ COALESCE(tag_data.tags, '{}'::text[]) AS tags,
193
+ COALESCE(tag_data.tag_confidences, '{}'::real[]) AS tag_confidences,
194
+ t.source_location,
195
+ t.approved_at,
196
+ CAST(
197
+ 1.0::double precision
198
+ - (t.embedding <=> $5::vector)::double precision
199
+ AS double precision
200
+ ) AS score
201
+ FROM weave.threads t
202
+ JOIN weave.documents d ON d.id = t.document_id
203
+ LEFT JOIN tag_data ON tag_data.document_id = d.id
204
+ WHERE t.organization_id = $4
205
+ AND t.retrieval_status = 'THREAD_RETRIEVAL_STATUS_APPROVED'
206
+ AND t.embedding IS NOT NULL
207
+ AND (
208
+ d.scope = 'DOCUMENT_SCOPE_ORG'
209
+ OR (d.scope = 'DOCUMENT_SCOPE_PRIVATE'
210
+ AND d.uploaded_by_user_id = $6)
211
+ OR (d.scope = 'DOCUMENT_SCOPE_RESTRICTED'
212
+ AND EXISTS (
213
+ SELECT 1
214
+ FROM weave.user_sensitivity_clearances c
215
+ WHERE c.organization_id = $4
216
+ AND c.user_id = $6
217
+ AND cardinality(d.sensitivity_tags) = 1
218
+ AND c.sensitivity_tag_slug = d.sensitivity_tags[1]
219
+ ))
220
+ )
221
+ AND (cardinality($7::text[]) = 0 OR tag_data.tags && $7::text[] OR d.sensitivity_tags && $7::text[])
222
+ AND (cardinality($8::text[]) = 0 OR d.sensitivity_tags && $8::text[])
223
+ AND (cardinality($9::text[]) = 0 OR d.scope = ANY($9::text[]))
224
+ AND ($10::timestamptz IS NULL OR d.uploaded_at >= $10::timestamptz)
225
+ AND ($11::timestamptz IS NULL OR d.uploaded_at <= $11::timestamptz)
226
+ )
227
+ SELECT
228
+ document_id,
229
+ document_name,
230
+ mime_type,
231
+ scope,
232
+ sensitivity_tags,
233
+ tags,
234
+ tag_confidences,
235
+ uploaded_at,
236
+ MAX(score)::double precision AS score,
237
+ COUNT(*)::int AS matched_thread_count,
238
+ (array_agg(thread_id ORDER BY score DESC, approved_at DESC))[1] AS best_thread_id,
239
+ (array_agg(text ORDER BY score DESC, approved_at DESC))[1] AS best_text,
240
+ (array_agg(classification ORDER BY score DESC, approved_at DESC))[1] AS best_classification,
241
+ (array_agg(source_location ORDER BY score DESC, approved_at DESC))[1] AS best_source_location
242
+ FROM matches
243
+ WHERE score >= $1::double precision
244
+ GROUP BY
245
+ document_id,
246
+ document_name,
247
+ mime_type,
248
+ scope,
249
+ sensitivity_tags,
250
+ tags,
251
+ tag_confidences,
252
+ uploaded_at
253
+ ORDER BY score DESC, uploaded_at DESC
254
+ LIMIT $3 OFFSET $2`;
255
+ async function searchAccessibleDocumentsSemantic(client, args) {
256
+ const result = await client.query({
257
+ text: exports.searchAccessibleDocumentsSemanticQuery,
258
+ values: [args.minSimilarity, args.pageOffset, args.resultLimit, args.organizationId, args.queryEmbedding, args.actingUserId, args.tags, args.restrictedTags, args.scopes, args.uploadedAfter, args.uploadedBefore],
259
+ rowMode: "array"
260
+ });
261
+ return result.rows.map(row => {
262
+ return {
263
+ documentId: row[0],
264
+ documentName: row[1],
265
+ mimeType: row[2],
266
+ scope: row[3],
267
+ sensitivityTags: row[4],
268
+ tags: row[5],
269
+ tagConfidences: row[6],
270
+ uploadedAt: row[7],
271
+ score: row[8],
272
+ matchedThreadCount: row[9],
273
+ bestThreadId: row[10],
274
+ bestText: row[11],
275
+ bestClassification: row[12],
276
+ bestSourceLocation: row[13]
277
+ };
278
+ });
279
+ }
169
280
  exports.searchApprovedThreadsSemanticByKnowledgeTypesQuery = `-- name: SearchApprovedThreadsSemanticByKnowledgeTypes :many
170
281
  SELECT
171
282
  t.id AS thread_id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weave-typescript",
3
- "version": "0.28.0",
3
+ "version": "0.30.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -31,7 +31,7 @@
31
31
  "devDependencies": {
32
32
  "@types/node": "^25.2.0",
33
33
  "@types/pg": "^8.15.5",
34
- "@typescript/native-preview": "7.0.0-dev.20260422.1"
34
+ "@typescript/native-preview": "7.0.0-dev.20260426.1"
35
35
  },
36
36
  "scripts": {
37
37
  "test": "node tools/sqlcgen.test.js",