@ghostpaw/affinity 0.1.6 → 0.2.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/index.cjs CHANGED
@@ -390,11 +390,32 @@ function initContactMergesTables(db) {
390
390
  );
391
391
  }
392
392
 
393
+ // src/merges/init_dismissed_duplicates_tables.ts
394
+ function initDismissedDuplicatesTables(db) {
395
+ db.exec(`
396
+ CREATE TABLE IF NOT EXISTS dismissed_duplicates (
397
+ left_id INTEGER NOT NULL,
398
+ right_id INTEGER NOT NULL,
399
+ reason TEXT,
400
+ dismissed_at INTEGER NOT NULL,
401
+ PRIMARY KEY (left_id, right_id),
402
+ CHECK (left_id < right_id)
403
+ )
404
+ `);
405
+ db.exec(
406
+ "CREATE INDEX IF NOT EXISTS idx_dismissed_duplicates_left ON dismissed_duplicates(left_id)"
407
+ );
408
+ db.exec(
409
+ "CREATE INDEX IF NOT EXISTS idx_dismissed_duplicates_right ON dismissed_duplicates(right_id)"
410
+ );
411
+ }
412
+
393
413
  // src/init_affinity_tables.ts
394
414
  function initAffinityTables(db) {
395
415
  initContactsTables(db);
396
416
  initContactRollupsTables(db);
397
417
  initContactMergesTables(db);
418
+ initDismissedDuplicatesTables(db);
398
419
  initIdentitiesTables(db);
399
420
  initLinksTables(db);
400
421
  initLinkRollupsTables(db);
@@ -502,6 +523,7 @@ __export(read_exports, {
502
523
  getMergeHistory: () => getMergeHistory,
503
524
  getOwnerProfile: () => getOwnerProfile,
504
525
  listContacts: () => listContacts,
526
+ listDismissedDuplicates: () => listDismissedDuplicates,
505
527
  listDuplicateCandidates: () => listDuplicateCandidates,
506
528
  listMoments: () => listMoments,
507
529
  listObservedLinks: () => listObservedLinks,
@@ -1354,8 +1376,24 @@ function listDuplicateCandidates(db, filters, options) {
1354
1376
  }
1355
1377
  }
1356
1378
  }
1379
+ const dismissedRows = db.prepare("SELECT left_id, right_id FROM dismissed_duplicates").all();
1380
+ const dismissedSet = new Set(
1381
+ dismissedRows.map((r) => pairKey(r.left_id, r.right_id))
1382
+ );
1383
+ const includeDismissed = filters?.includeDismissed === true;
1384
+ for (const candidate of pairs.values()) {
1385
+ if (dismissedSet.has(
1386
+ pairKey(candidate.leftContactId, candidate.rightContactId)
1387
+ )) {
1388
+ candidate.dismissed = true;
1389
+ }
1390
+ }
1357
1391
  const minScore = filters?.minScore ?? 0;
1358
- return [...pairs.values()].filter((candidate) => candidate.matchScore >= minScore).sort((left, right) => {
1392
+ return [...pairs.values()].filter((candidate) => {
1393
+ if (candidate.matchScore < minScore) return false;
1394
+ if (candidate.dismissed === true && !includeDismissed) return false;
1395
+ return true;
1396
+ }).sort((left, right) => {
1359
1397
  const leftExact = left.matchScore === 1 ? 1 : 0;
1360
1398
  const rightExact = right.matchScore === 1 ? 1 : 0;
1361
1399
  return rightExact - leftExact || right.matchScore - left.matchScore;
@@ -3418,6 +3456,12 @@ function mergeContacts(db, input) {
3418
3456
  `INSERT INTO contact_merges (winner_contact_id, loser_contact_id, merged_at, reason_summary, manual)
3419
3457
  VALUES (?, ?, ?, ?, 1)`
3420
3458
  ).run(winnerId, loserId, now, reasonSummary);
3459
+ db.prepare(
3460
+ "DELETE FROM dismissed_duplicates WHERE left_id = ? OR right_id = ?"
3461
+ ).run(loserId, loserId);
3462
+ db.prepare(
3463
+ "DELETE FROM dismissed_duplicates WHERE left_id = ? OR right_id = ?"
3464
+ ).run(winnerId, winnerId);
3421
3465
  db.prepare(
3422
3466
  "DELETE FROM link_rollups WHERE link_id IN (SELECT id FROM links WHERE removed_at IS NOT NULL)"
3423
3467
  ).run();
@@ -3445,6 +3489,117 @@ function mergeContacts(db, input) {
3445
3489
  });
3446
3490
  }
3447
3491
 
3492
+ // src/merges/receipts.ts
3493
+ function buildDismissalMutationReceipt(primary, partial) {
3494
+ const normalized = normalizeMutationReceiptPartial(partial);
3495
+ return {
3496
+ primary,
3497
+ created: normalized.created,
3498
+ updated: normalized.updated,
3499
+ archived: normalized.archived,
3500
+ removed: normalized.removed,
3501
+ affectedLinks: normalized.affectedLinks,
3502
+ derivedEffects: normalized.derivedEffects
3503
+ };
3504
+ }
3505
+
3506
+ // src/merges/dismiss_duplicate.ts
3507
+ function canonicalize(a, b) {
3508
+ return {
3509
+ leftContactId: Math.min(a, b),
3510
+ rightContactId: Math.max(a, b)
3511
+ };
3512
+ }
3513
+ function dismissDuplicate(db, leftContactId, rightContactId, reason, now) {
3514
+ return withTransaction(db, () => {
3515
+ if (leftContactId === rightContactId) {
3516
+ throw new AffinityValidationError(
3517
+ "cannot dismiss a contact as a duplicate of itself"
3518
+ );
3519
+ }
3520
+ const left = getContactRowById(db, leftContactId);
3521
+ if (!left) {
3522
+ throw new AffinityNotFoundError(`contact ${leftContactId} not found`);
3523
+ }
3524
+ if (left.lifecycle_state === "merged") {
3525
+ throw new AffinityStateError(
3526
+ `contact ${leftContactId} is merged and cannot be dismissed`
3527
+ );
3528
+ }
3529
+ const right = getContactRowById(db, rightContactId);
3530
+ if (!right) {
3531
+ throw new AffinityNotFoundError(`contact ${rightContactId} not found`);
3532
+ }
3533
+ if (right.lifecycle_state === "merged") {
3534
+ throw new AffinityStateError(
3535
+ `contact ${rightContactId} is merged and cannot be dismissed`
3536
+ );
3537
+ }
3538
+ const pair = canonicalize(leftContactId, rightContactId);
3539
+ const resolvedNow = resolveNow(now);
3540
+ const resolvedReason = reason === void 0 || reason === null ? null : (() => {
3541
+ const t = reason.trim();
3542
+ return t.length === 0 ? null : t;
3543
+ })();
3544
+ db.prepare(
3545
+ `INSERT INTO dismissed_duplicates (left_id, right_id, reason, dismissed_at)
3546
+ VALUES (?, ?, ?, ?)
3547
+ ON CONFLICT(left_id, right_id) DO UPDATE SET
3548
+ reason = excluded.reason,
3549
+ dismissed_at = excluded.dismissed_at`
3550
+ ).run(pair.leftContactId, pair.rightContactId, resolvedReason, resolvedNow);
3551
+ return buildDismissalMutationReceipt(pair);
3552
+ });
3553
+ }
3554
+
3555
+ // src/merges/undismiss_duplicate.ts
3556
+ function canonicalize2(a, b) {
3557
+ return {
3558
+ leftContactId: Math.min(a, b),
3559
+ rightContactId: Math.max(a, b)
3560
+ };
3561
+ }
3562
+ function undismissDuplicate(db, leftContactId, rightContactId) {
3563
+ return withTransaction(db, () => {
3564
+ if (leftContactId === rightContactId) {
3565
+ throw new AffinityValidationError(
3566
+ "cannot undismiss a contact from itself"
3567
+ );
3568
+ }
3569
+ const left = getContactRowById(db, leftContactId);
3570
+ if (!left) {
3571
+ throw new AffinityNotFoundError(`contact ${leftContactId} not found`);
3572
+ }
3573
+ const right = getContactRowById(db, rightContactId);
3574
+ if (!right) {
3575
+ throw new AffinityNotFoundError(`contact ${rightContactId} not found`);
3576
+ }
3577
+ const pair = canonicalize2(leftContactId, rightContactId);
3578
+ db.prepare(
3579
+ "DELETE FROM dismissed_duplicates WHERE left_id = ? AND right_id = ?"
3580
+ ).run(pair.leftContactId, pair.rightContactId);
3581
+ return buildDismissalMutationReceipt(pair);
3582
+ });
3583
+ }
3584
+
3585
+ // src/merges/list_dismissed_duplicates.ts
3586
+ function listDismissedDuplicates(db, options) {
3587
+ assertDefaultOrdering("listDismissedDuplicates", options);
3588
+ const { limit, offset } = resolveListLimitOffset(options);
3589
+ const rows = db.prepare(
3590
+ `SELECT left_id, right_id, reason, dismissed_at
3591
+ FROM dismissed_duplicates
3592
+ ORDER BY dismissed_at DESC
3593
+ LIMIT ? OFFSET ?`
3594
+ ).all(limit, offset);
3595
+ return rows.map((row) => ({
3596
+ leftContactId: row.left_id,
3597
+ rightContactId: row.right_id,
3598
+ reason: row.reason,
3599
+ dismissedAt: row.dismissed_at
3600
+ }));
3601
+ }
3602
+
3448
3603
  // src/events/get_contact_journal.ts
3449
3604
  function getContactJournal(db, contactId, options) {
3450
3605
  assertDefaultOrdering("getContactJournal", options);
@@ -5333,6 +5488,9 @@ __export(tools_exports, {
5333
5488
  manageDateAnchorTool: () => manageDateAnchorTool,
5334
5489
  manageDateAnchorToolHandler: () => manageDateAnchorToolHandler,
5335
5490
  manageDateAnchorToolName: () => manageDateAnchorToolName,
5491
+ manageDuplicateDismissalTool: () => manageDuplicateDismissalTool,
5492
+ manageDuplicateDismissalToolHandler: () => manageDuplicateDismissalToolHandler,
5493
+ manageDuplicateDismissalToolName: () => manageDuplicateDismissalToolName,
5336
5494
  manageIdentityTool: () => manageIdentityTool,
5337
5495
  manageIdentityToolHandler: () => manageIdentityToolHandler,
5338
5496
  manageIdentityToolName: () => manageIdentityToolName,
@@ -5455,6 +5613,7 @@ var reviewAffinityToolName = "review_affinity";
5455
5613
  var inspectAffinityItemToolName = "inspect_affinity_item";
5456
5614
  var manageContactToolName = "manage_contact";
5457
5615
  var mergeContactsToolName = "merge_contacts";
5616
+ var manageDuplicateDismissalToolName = "manage_duplicate_dismissal";
5458
5617
  var manageIdentityToolName = "manage_identity";
5459
5618
  var manageRelationshipToolName = "manage_relationship";
5460
5619
  var recordEventToolName = "record_event";
@@ -6706,7 +6865,7 @@ var manageContactTool = defineAffinityTool({
6706
6865
  handler: manageContactToolHandler
6707
6866
  });
6708
6867
 
6709
- // src/tools/manage_date_anchor_tool.ts
6868
+ // src/tools/manage_duplicate_dismissal_tool.ts
6710
6869
  function contactLocatorSchema4(description) {
6711
6870
  return {
6712
6871
  type: "object",
@@ -6724,6 +6883,86 @@ function contactLocatorSchema4(description) {
6724
6883
  description
6725
6884
  };
6726
6885
  }
6886
+ function manageDuplicateDismissalToolHandler(db, input) {
6887
+ return withToolHandling(() => {
6888
+ const left = resolveContactLocator(db, input.left, "left");
6889
+ if (!left.ok) {
6890
+ return left.result;
6891
+ }
6892
+ const right = resolveContactLocator(db, input.right, "right");
6893
+ if (!right.ok) {
6894
+ return right.result;
6895
+ }
6896
+ if (input.action === "dismiss") {
6897
+ const receipt2 = dismissDuplicate(
6898
+ db,
6899
+ left.value.id,
6900
+ right.value.id,
6901
+ input.reason ?? null
6902
+ );
6903
+ return toolSuccess(
6904
+ `Dismissed pair #${receipt2.primary.leftContactId} / #${receipt2.primary.rightContactId}.`,
6905
+ { action: "dismiss", primary: receipt2.primary }
6906
+ );
6907
+ }
6908
+ const receipt = undismissDuplicate(db, left.value.id, right.value.id);
6909
+ return toolSuccess(
6910
+ `Un-dismissed pair #${receipt.primary.leftContactId} / #${receipt.primary.rightContactId}.`,
6911
+ { action: "undismiss", primary: receipt.primary }
6912
+ );
6913
+ }, "Duplicate dismissal failed.");
6914
+ }
6915
+ var manageDuplicateDismissalTool = defineAffinityTool({
6916
+ name: manageDuplicateDismissalToolName,
6917
+ description: "Dismiss or un-dismiss a duplicate candidate pair so it does not resurface in listDuplicateCandidates.",
6918
+ whenToUse: "Use dismiss after confirming two contacts are different people (not duplicates). Use undismiss to re-surface a pair for re-evaluation.",
6919
+ whenNotToUse: "Do not use this to merge contacts \u2014 use merge_contacts for confirmed duplicates.",
6920
+ sideEffects: "writes_state",
6921
+ readOnly: false,
6922
+ supportsClarification: true,
6923
+ targetKinds: ["contact"],
6924
+ inputDescriptions: {
6925
+ action: "dismiss to suppress the pair; undismiss to re-surface it.",
6926
+ left: "One contact of the pair.",
6927
+ right: "The other contact of the pair.",
6928
+ reason: "Optional reason for the dismissal (audit trail)."
6929
+ },
6930
+ outputDescription: "Returns the dismissal receipt with the canonical pair identifiers.",
6931
+ inputSchema: objectSchema(
6932
+ {
6933
+ action: enumSchema("Action to perform.", ["dismiss", "undismiss"]),
6934
+ left: contactLocatorSchema4(
6935
+ "Left contact. Provide contactId or identity."
6936
+ ),
6937
+ right: contactLocatorSchema4(
6938
+ "Right contact. Provide contactId or identity."
6939
+ ),
6940
+ reason: nullableStringSchema("Optional reason for the dismissal.")
6941
+ },
6942
+ ["action", "left", "right"],
6943
+ "Dismiss or un-dismiss a duplicate candidate pair."
6944
+ ),
6945
+ handler: manageDuplicateDismissalToolHandler
6946
+ });
6947
+
6948
+ // src/tools/manage_date_anchor_tool.ts
6949
+ function contactLocatorSchema5(description) {
6950
+ return {
6951
+ type: "object",
6952
+ properties: {
6953
+ contactId: integerSchema("Exact contact id."),
6954
+ identity: objectSchema(
6955
+ {
6956
+ type: stringSchema("Identity type."),
6957
+ value: stringSchema("Identity value.")
6958
+ },
6959
+ ["type", "value"],
6960
+ "Contact identity locator."
6961
+ )
6962
+ },
6963
+ description
6964
+ };
6965
+ }
6727
6966
  function linkLocatorSchema3(description) {
6728
6967
  return {
6729
6968
  type: "object",
@@ -6814,7 +7053,7 @@ var manageDateAnchorTool = defineAffinityTool({
6814
7053
  target: objectSchema(
6815
7054
  {
6816
7055
  kind: enumSchema("Target kind.", ["contact", "link"]),
6817
- contact: contactLocatorSchema4(
7056
+ contact: contactLocatorSchema5(
6818
7057
  "Contact locator. Required when kind=contact. Provide contactId or identity."
6819
7058
  ),
6820
7059
  link: linkLocatorSchema3(
@@ -6968,6 +7207,9 @@ function addIdentity(db, contactId, input) {
6968
7207
  throw new AffinityInvariantError("inserted identity not found");
6969
7208
  }
6970
7209
  refreshContactRollup(db, contactId, now);
7210
+ db.prepare(
7211
+ "DELETE FROM dismissed_duplicates WHERE left_id = ? OR right_id = ?"
7212
+ ).run(contactId, contactId);
6971
7213
  return buildIdentityMutationReceipt(mapIdentityRowToIdentityRecord(row), {
6972
7214
  created: [{ kind: "identity", id }]
6973
7215
  });
@@ -6991,6 +7233,9 @@ function removeIdentity(db, identityId, removedAt) {
6991
7233
  "UPDATE identities SET removed_at = ?, updated_at = ? WHERE id = ?"
6992
7234
  ).run(now, now, identityId);
6993
7235
  refreshContactRollup(db, row.contact_id, now);
7236
+ db.prepare(
7237
+ "DELETE FROM dismissed_duplicates WHERE left_id = ? OR right_id = ?"
7238
+ ).run(row.contact_id, row.contact_id);
6994
7239
  return buildIdentityMutationReceipt(primary, {
6995
7240
  removed: [{ kind: "identity", id: identityId }]
6996
7241
  });
@@ -7069,7 +7314,7 @@ function verifyIdentity(db, identityId, verifiedAt) {
7069
7314
  }
7070
7315
 
7071
7316
  // src/tools/manage_identity_tool.ts
7072
- function contactLocatorSchema5(description) {
7317
+ function contactLocatorSchema6(description) {
7073
7318
  return {
7074
7319
  type: "object",
7075
7320
  properties: {
@@ -7148,7 +7393,7 @@ var manageIdentityTool = defineAffinityTool({
7148
7393
  "verify",
7149
7394
  "remove"
7150
7395
  ]),
7151
- contact: contactLocatorSchema5(
7396
+ contact: contactLocatorSchema6(
7152
7397
  "Target contact. Required when action=add. Provide contactId or identity."
7153
7398
  ),
7154
7399
  input: objectSchema(
@@ -7188,7 +7433,7 @@ var manageIdentityTool = defineAffinityTool({
7188
7433
  });
7189
7434
 
7190
7435
  // src/tools/manage_relationship_tool.ts
7191
- function contactLocatorSchema6(description) {
7436
+ function contactLocatorSchema7(description) {
7192
7437
  return {
7193
7438
  type: "object",
7194
7439
  properties: {
@@ -7344,10 +7589,10 @@ var manageRelationshipTool = defineAffinityTool({
7344
7589
  "set_structural_tie",
7345
7590
  "remove_structural_tie"
7346
7591
  ]),
7347
- from: contactLocatorSchema6(
7592
+ from: contactLocatorSchema7(
7348
7593
  "Source contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity."
7349
7594
  ),
7350
- to: contactLocatorSchema6(
7595
+ to: contactLocatorSchema7(
7351
7596
  "Target contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity."
7352
7597
  ),
7353
7598
  kind: stringSchema(
@@ -7389,7 +7634,7 @@ var manageRelationshipTool = defineAffinityTool({
7389
7634
  });
7390
7635
 
7391
7636
  // src/tools/merge_contacts_tool.ts
7392
- function contactLocatorSchema7(description) {
7637
+ function contactLocatorSchema8(description) {
7393
7638
  return {
7394
7639
  type: "object",
7395
7640
  properties: {
@@ -7446,10 +7691,10 @@ var mergeContactsTool = defineAffinityTool({
7446
7691
  outputDescription: "Returns the merge receipt with rewired entities and affected-link information.",
7447
7692
  inputSchema: objectSchema(
7448
7693
  {
7449
- winner: contactLocatorSchema7(
7694
+ winner: contactLocatorSchema8(
7450
7695
  "Winner contact. Provide contactId or identity."
7451
7696
  ),
7452
- loser: contactLocatorSchema7(
7697
+ loser: contactLocatorSchema8(
7453
7698
  "Loser contact. Provide contactId or identity."
7454
7699
  ),
7455
7700
  reasonSummary: stringSchema("Optional merge reason."),
@@ -7620,7 +7865,7 @@ function buildChartOptions(input) {
7620
7865
  ...input.contactIds === void 0 ? {} : { contactIds: input.contactIds }
7621
7866
  };
7622
7867
  }
7623
- function contactLocatorSchema8(description) {
7868
+ function contactLocatorSchema9(description) {
7624
7869
  return {
7625
7870
  type: "object",
7626
7871
  properties: {
@@ -7711,6 +7956,14 @@ function validateReviewInput(input) {
7711
7956
  "Use `contactIds` only with duplicate-candidate or chart review views."
7712
7957
  );
7713
7958
  }
7959
+ if (input.includeDismissed !== void 0 && input.view !== "contacts.duplicates") {
7960
+ return toolFailure(
7961
+ "protocol",
7962
+ "invalid_input",
7963
+ "The `includeDismissed` filter is not valid for this review view.",
7964
+ "Use `includeDismissed` only with the contacts.duplicates review view."
7965
+ );
7966
+ }
7714
7967
  return null;
7715
7968
  }
7716
7969
  function duplicateCandidateItem(candidate) {
@@ -7767,6 +8020,15 @@ function mergeHistoryItem(record) {
7767
8020
  snippet: record.reasonSummary ?? void 0
7768
8021
  };
7769
8022
  }
8023
+ function dismissedPairItem(record) {
8024
+ return {
8025
+ kind: "contact",
8026
+ id: record.leftContactId,
8027
+ title: `Dismissed pair: #${record.leftContactId} and #${record.rightContactId}`,
8028
+ subtitle: record.reason ?? "no reason given",
8029
+ snippet: `dismissed at ${record.dismissedAt}`
8030
+ };
8031
+ }
7770
8032
  function compactFilters(input) {
7771
8033
  return Object.fromEntries(
7772
8034
  Object.entries(input).filter(
@@ -7802,7 +8064,8 @@ function reviewAffinityToolHandler(db, input) {
7802
8064
  {
7803
8065
  ...input.contactIds === void 0 ? {} : { contactIds: input.contactIds },
7804
8066
  ...input.exactOnly === void 0 ? {} : { exactOnly: input.exactOnly },
7805
- ...input.minScore === void 0 ? {} : { minScore: input.minScore }
8067
+ ...input.minScore === void 0 ? {} : { minScore: input.minScore },
8068
+ ...input.includeDismissed === void 0 ? {} : { includeDismissed: input.includeDismissed }
7806
8069
  },
7807
8070
  options
7808
8071
  ).map(duplicateCandidateItem);
@@ -7983,6 +8246,9 @@ function reviewAffinityToolHandler(db, input) {
7983
8246
  );
7984
8247
  break;
7985
8248
  }
8249
+ case "merges.dismissed":
8250
+ items = listDismissedDuplicates(db, options).map(dismissedPairItem);
8251
+ break;
7986
8252
  }
7987
8253
  return toolSuccess(
7988
8254
  summarizeCount(items.length, "item"),
@@ -8033,6 +8299,7 @@ var reviewAffinityTool = defineAffinityTool({
8033
8299
  horizonDays: "Optional horizon filter for commitments or upcoming dates.",
8034
8300
  exactOnly: "Whether duplicate review should only include exact identity matches.",
8035
8301
  minScore: "Optional minimum duplicate score.",
8302
+ includeDismissed: "Whether dismissed pairs should be included in duplicate review (marked with dismissed flag).",
8036
8303
  since: "Optional lower timestamp bound for time-based views.",
8037
8304
  until: "Optional upper timestamp bound for time-based views.",
8038
8305
  limit: "Optional result limit.",
@@ -8054,9 +8321,10 @@ var reviewAffinityTool = defineAffinityTool({
8054
8321
  "links.radar",
8055
8322
  "dates.upcoming",
8056
8323
  "graph.chart",
8057
- "merges.history"
8324
+ "merges.history",
8325
+ "merges.dismissed"
8058
8326
  ]),
8059
- contact: contactLocatorSchema8("Optional target contact locator."),
8327
+ contact: contactLocatorSchema9("Optional target contact locator."),
8060
8328
  link: linkLocatorSchema5("Optional target link locator."),
8061
8329
  contactIds: arraySchema(
8062
8330
  integerSchema("Contact id."),
@@ -8107,6 +8375,9 @@ var reviewAffinityTool = defineAffinityTool({
8107
8375
  horizonDays: integerSchema("Optional horizon-days filter."),
8108
8376
  exactOnly: booleanSchema("Whether duplicate review is exact-only."),
8109
8377
  minScore: numberSchema("Optional duplicate minimum score."),
8378
+ includeDismissed: booleanSchema(
8379
+ "Whether dismissed pairs are included in duplicate review (marked with dismissed flag)."
8380
+ ),
8110
8381
  since: integerSchema("Optional lower timestamp bound."),
8111
8382
  until: integerSchema("Optional upper timestamp bound."),
8112
8383
  limit: integerSchema("Optional result limit."),
@@ -8205,6 +8476,7 @@ var affinityTools = [
8205
8476
  inspectAffinityItemTool,
8206
8477
  manageContactTool,
8207
8478
  mergeContactsTool,
8479
+ manageDuplicateDismissalTool,
8208
8480
  manageIdentityTool,
8209
8481
  manageRelationshipTool,
8210
8482
  recordEventTool,
@@ -8306,6 +8578,21 @@ var affinityToolMappings = [
8306
8578
  action: "set_lifecycle"
8307
8579
  },
8308
8580
  { source: "mergeContacts", tool: mergeContactsToolName },
8581
+ {
8582
+ source: "dismissDuplicate",
8583
+ tool: manageDuplicateDismissalToolName,
8584
+ action: "dismiss"
8585
+ },
8586
+ {
8587
+ source: "undismissDuplicate",
8588
+ tool: manageDuplicateDismissalToolName,
8589
+ action: "undismiss"
8590
+ },
8591
+ {
8592
+ source: "listDismissedDuplicates",
8593
+ tool: reviewAffinityToolName,
8594
+ view: "merges.dismissed"
8595
+ },
8309
8596
  { source: "addIdentity", tool: manageIdentityToolName, action: "add" },
8310
8597
  { source: "reviseIdentity", tool: manageIdentityToolName, action: "revise" },
8311
8598
  { source: "verifyIdentity", tool: manageIdentityToolName, action: "verify" },
@@ -8387,6 +8674,7 @@ __export(write_exports, {
8387
8674
  addDateAnchor: () => addDateAnchor,
8388
8675
  addIdentity: () => addIdentity,
8389
8676
  createContact: () => createContact,
8677
+ dismissDuplicate: () => dismissDuplicate,
8390
8678
  mergeContacts: () => mergeContacts,
8391
8679
  overrideLinkState: () => overrideLinkState,
8392
8680
  recordCommitment: () => recordCommitment,
@@ -8407,6 +8695,7 @@ __export(write_exports, {
8407
8695
  setAttribute: () => setAttribute,
8408
8696
  setContactLifecycle: () => setContactLifecycle,
8409
8697
  setStructuralTie: () => setStructuralTie,
8698
+ undismissDuplicate: () => undismissDuplicate,
8410
8699
  unsetAttribute: () => unsetAttribute,
8411
8700
  verifyIdentity: () => verifyIdentity
8412
8701
  });