lumnisai 0.5.25 → 0.5.27

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
@@ -949,6 +949,9 @@ class CrmResource {
949
949
  * `crmRecordId`. Stale links (record deleted in the CRM) are detected
950
950
  * and re-created automatically.
951
951
  *
952
+ * Works with or without a `campaign_prospects` row — search-sourced
953
+ * prospects are enriched from profile cache when needed.
954
+ *
952
955
  * @example
953
956
  * ```typescript
954
957
  * const result = await client.crm.syncProspect({
@@ -968,16 +971,13 @@ class CrmResource {
968
971
  * render a "linked" indicator for the ones that come back true.
969
972
  *
970
973
  * Layered cache on the server side: persistent positive matches are
971
- * served from the `campaign_prospects.crm_record_id` column, negative
972
- * results are served from a Redis cache (TTL configured by
973
- * `CRM_MATCH_NEGATIVE_CACHE_TTL_SECONDS`). Only the leftover unknowns
974
- * fan out to the live CRM, bounded by
974
+ * served from the `campaign_prospects.crm_record_id` column and the
975
+ * local `crm_contacts` ledger; negative results are served from a Redis
976
+ * cache (TTL configured by `CRM_MATCH_NEGATIVE_CACHE_TTL_SECONDS`).
977
+ * Only the leftover unknowns fan out to the live CRM, bounded by
975
978
  * `CRM_MATCH_LIVE_SEARCH_PARALLELISM`.
976
979
  *
977
- * Note: HubSpot does not expose a LinkedIn-URL search field through
978
- * Composio, so for `provider: 'hubspot'` URLs that aren't already in
979
- * the persistent cache will always come back `linked: false`. The
980
- * sync endpoint still reconciles via email when available.
980
+ * Provider-id/URN inputs are resolved to vanity before matching.
981
981
  *
982
982
  * @example
983
983
  * ```typescript
@@ -994,6 +994,46 @@ class CrmResource {
994
994
  async matchBatch(data) {
995
995
  return this.http.post("/crm/prospects/match-batch", data);
996
996
  }
997
+ /**
998
+ * Trigger a full mirror of the owner's CRM contact book into the local
999
+ * `crm_contacts` ledger. Returns immediately (`202`); poll
1000
+ * {@link getContactsSyncStatus} for progress.
1001
+ */
1002
+ async syncContacts(data) {
1003
+ return this.http.post("/crm/contacts/sync", data);
1004
+ }
1005
+ /**
1006
+ * Ledger sync freshness for an owner+provider: connection state, whether a
1007
+ * sync is in progress, last reconcile time, and row count in the ledger.
1008
+ */
1009
+ async getContactsSyncStatus(userId, provider) {
1010
+ return this.http.get("/crm/contacts/sync-status", {
1011
+ params: { userId, provider }
1012
+ });
1013
+ }
1014
+ /**
1015
+ * Grant a member the right to exclude against an owner's synced CRM ledger
1016
+ * (all providers for that owner). Typically called by the FE on org join.
1017
+ */
1018
+ async grantExclusionGrant(data) {
1019
+ return this.http.post("/crm/exclusion-grants", data);
1020
+ }
1021
+ /**
1022
+ * Revoke a member's access to an owner's CRM exclusion ledger.
1023
+ */
1024
+ async revokeExclusionGrant(data) {
1025
+ return this.http.delete("/crm/exclusion-grants", {
1026
+ body: data
1027
+ });
1028
+ }
1029
+ /**
1030
+ * List CRM owners whose exclusion ledger a member may read (via grants).
1031
+ */
1032
+ async listExclusionGrants(memberUserId) {
1033
+ return this.http.get("/crm/exclusion-grants", {
1034
+ params: { memberUserId }
1035
+ });
1036
+ }
997
1037
  }
998
1038
 
999
1039
  class EmailResource {
@@ -1177,6 +1217,10 @@ class EnrichmentResource {
1177
1217
  * @param params.onlyVerifiedEmail - Only return verified emails (default: true)
1178
1218
  * @param params.enrichMobile - Include mobile enrichment, 10x cost (default: false)
1179
1219
  * @param params.onlyVerifiedMobile - Only return verified mobiles (default: false)
1220
+ * @param params.deepWebFallback - For vendor-misses, discover contacts from the
1221
+ * organization's official public web pages. Findings come back in
1222
+ * `result.deepWebFindings` with source URLs + confidence tiers and never
1223
+ * overwrite `person.email`. Pass false to disable (default: true)
1180
1224
  * @returns Promise resolving to enrichment results
1181
1225
  *
1182
1226
  * @example
@@ -3508,6 +3552,9 @@ class ResponsesResource {
3508
3552
  * @param options - Optional search parameters
3509
3553
  * @param options.limit - Maximum number of results (1-100, default: 20)
3510
3554
  * @param options.dataSources - Specific data sources to use: ["PDL", "CORESIGNAL", "CRUST_DATA"]
3555
+ * @param options.excludeCrmContacts - Exclude people in the acting user's synced CRM ledger; @default true (via request `options`)
3556
+ * @param options.crmExclusionOwners - Granted owner ledgers to exclude against (user id or email)
3557
+ * @param options.crmNameCompanyMatch - Also exclude by exact name+company; @default true
3511
3558
  * @returns Response with structured_response containing:
3512
3559
  * - candidates: List of person results
3513
3560
  * - totalFound: Total unique candidates found
@@ -3528,6 +3575,15 @@ class ResponsesResource {
3528
3575
  params.dataSources = options.dataSources;
3529
3576
  if (Object.keys(params).length > 0)
3530
3577
  request.specializedAgentParams = params;
3578
+ const crmOptions = {};
3579
+ if (options.excludeCrmContacts !== void 0)
3580
+ crmOptions.excludeCrmContacts = options.excludeCrmContacts;
3581
+ if (options.crmExclusionOwners)
3582
+ crmOptions.crmExclusionOwners = options.crmExclusionOwners;
3583
+ if (options.crmNameCompanyMatch !== void 0)
3584
+ crmOptions.crmNameCompanyMatch = options.crmNameCompanyMatch;
3585
+ if (Object.keys(crmOptions).length > 0)
3586
+ request.options = crmOptions;
3531
3587
  }
3532
3588
  return this.create(request);
3533
3589
  }
@@ -3549,7 +3605,14 @@ class ResponsesResource {
3549
3605
  * @param options.excludeProfiles - LinkedIn URLs to exclude from results
3550
3606
  * @param options.excludePreviouslyContacted - Exclude previously contacted people
3551
3607
  * @param options.excludeNames - Names to exclude from results
3608
+ * @param options.excludeCrmContacts - Exclude people in the acting user's synced CRM ledger; @default true
3609
+ * @param options.crmExclusionOwners - Granted owner ledgers to exclude against (user id or email)
3610
+ * @param options.crmNameCompanyMatch - Also exclude by exact name+company; @default true
3552
3611
  * @param options.searchJobSignal - CrustData job-listing signal search (decision makers at hiring companies); true | false | 'auto'
3612
+ * @param options.deepVerify - Web verification for org/location/third-party criteria: 'auto' (default), 'always', or 'off'
3613
+ * @param options.deepValidationUseRelevanceReranker - SLM relevance reranker for surfaced candidates (ranking-only); @default true
3614
+ * @param options.deepValidationBackfillBelowCriteria - Pad with criteria-failed candidates when under count; @default true
3615
+ * @param options.deepSearchCriteriaModel - Override criteria decomposition model (e.g. 'openai:gpt-5.4')
3553
3616
  * @returns Response with structured_response containing:
3554
3617
  * - candidates: Validated and scored candidates
3555
3618
  * - criteria: Generated/reused criteria definitions and classification
@@ -3560,8 +3623,11 @@ class ResponsesResource {
3560
3623
  messages: [{ role: "user", content: query }],
3561
3624
  specializedAgent: "deep_people_search"
3562
3625
  };
3626
+ const params = {
3627
+ deepValidationUseRelevanceReranker: options?.deepValidationUseRelevanceReranker ?? true,
3628
+ deepValidationBackfillBelowCriteria: options?.deepValidationBackfillBelowCriteria ?? true
3629
+ };
3563
3630
  if (options) {
3564
- const params = {};
3565
3631
  if (options.requestedCandidates !== void 0)
3566
3632
  params.requestedCandidates = options.requestedCandidates;
3567
3633
  if (options.dataSources)
@@ -3584,6 +3650,12 @@ class ResponsesResource {
3584
3650
  params.excludePreviouslyContacted = options.excludePreviouslyContacted;
3585
3651
  if (options.excludeNames)
3586
3652
  params.excludeNames = options.excludeNames;
3653
+ if (options.excludeCrmContacts !== void 0)
3654
+ params.excludeCrmContacts = options.excludeCrmContacts;
3655
+ if (options.crmExclusionOwners)
3656
+ params.crmExclusionOwners = options.crmExclusionOwners;
3657
+ if (options.crmNameCompanyMatch !== void 0)
3658
+ params.crmNameCompanyMatch = options.crmNameCompanyMatch;
3587
3659
  if (options.searchProfiles !== void 0)
3588
3660
  params.searchProfiles = options.searchProfiles;
3589
3661
  if (options.searchPosts !== void 0)
@@ -3612,9 +3684,12 @@ class ResponsesResource {
3612
3684
  params.postsExtractAuthor = options.postsExtractAuthor;
3613
3685
  if (options.searchJobSignal !== void 0)
3614
3686
  params.searchJobSignal = options.searchJobSignal;
3615
- if (Object.keys(params).length > 0)
3616
- request.specializedAgentParams = params;
3687
+ if (options.deepVerify !== void 0)
3688
+ params.deepVerify = options.deepVerify;
3689
+ if (options.deepSearchCriteriaModel)
3690
+ params.deepSearchCriteriaModel = options.deepSearchCriteriaModel;
3617
3691
  }
3692
+ request.specializedAgentParams = params;
3618
3693
  return this.create(request);
3619
3694
  }
3620
3695
  /**
@@ -3631,6 +3706,9 @@ class ResponsesResource {
3631
3706
  * Can be a string (criterion text) or an object with criterionText and optional suggestedColumnName.
3632
3707
  * Example string: 'Must have 5+ years Python experience'
3633
3708
  * Example object: { criterionText: 'Has ML experience', suggestedColumnName: 'ml_experience' }
3709
+ * @param options.deepValidationUseRelevanceReranker - SLM relevance reranker for surfaced candidates (ranking-only); @default true
3710
+ * @param options.deepValidationBackfillBelowCriteria - Pad with criteria-failed candidates when under count; @default true
3711
+ * @param options.deepSearchCriteriaModel - Override criteria decomposition model (e.g. 'openai:gpt-5.4')
3634
3712
  * @returns Response with structured_response containing:
3635
3713
  * - candidates: Scored candidates with validation results
3636
3714
  * - criteria: Generated/reused criteria definitions and classification
@@ -3640,7 +3718,9 @@ class ResponsesResource {
3640
3718
  messages: [{ role: "user", content: query }],
3641
3719
  specializedAgent: "people_scoring",
3642
3720
  specializedAgentParams: {
3643
- candidateProfiles
3721
+ candidateProfiles,
3722
+ deepValidationUseRelevanceReranker: options?.deepValidationUseRelevanceReranker ?? true,
3723
+ deepValidationBackfillBelowCriteria: options?.deepValidationBackfillBelowCriteria ?? true
3644
3724
  }
3645
3725
  };
3646
3726
  if (options) {
@@ -3656,6 +3736,8 @@ class ResponsesResource {
3656
3736
  request.specializedAgentParams.addCriterion = options.addCriterion;
3657
3737
  if (options.addAndRunCriterion)
3658
3738
  request.specializedAgentParams.addAndRunCriterion = options.addAndRunCriterion;
3739
+ if (options.deepSearchCriteriaModel)
3740
+ request.specializedAgentParams.deepSearchCriteriaModel = options.deepSearchCriteriaModel;
3659
3741
  }
3660
3742
  return this.create(request);
3661
3743
  }
@@ -3689,7 +3771,9 @@ class ResponsesResource {
3689
3771
  messages: [{ role: "user", content: query }],
3690
3772
  specializedAgent: "competitor_post_engagement"
3691
3773
  };
3692
- const params = {};
3774
+ const params = {
3775
+ deepValidationUseRelevanceReranker: options.deepValidationUseRelevanceReranker ?? true
3776
+ };
3693
3777
  if (options.company)
3694
3778
  params.company = options.company;
3695
3779
  if (options.competitors)
@@ -3755,7 +3839,9 @@ class ResponsesResource {
3755
3839
  messages: [{ role: "user", content: query }],
3756
3840
  specializedAgent: "competitor_rep_engagement"
3757
3841
  };
3758
- const params = {};
3842
+ const params = {
3843
+ deepValidationUseRelevanceReranker: options.deepValidationUseRelevanceReranker ?? true
3844
+ };
3759
3845
  if (options.company)
3760
3846
  params.company = options.company;
3761
3847
  if (options.competitors)