lumnisai 0.5.21 → 0.5.23

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.mjs CHANGED
@@ -657,6 +657,21 @@ class CampaignsResource {
657
657
  `/campaigns/${encodeURIComponent(campaignId)}/prospects/${encodeURIComponent(prospectId)}`
658
658
  );
659
659
  }
660
+ /**
661
+ * Transfer prospects from this campaign into another campaign owned by
662
+ * the same user. Omit prospectIds to transfer every prospect.
663
+ *
664
+ * In-flight actions are cancelled and the prospect is re-evaluated under
665
+ * the target campaign's playbook; its action history and email threads
666
+ * follow it. Prospects already present in the target are skipped and
667
+ * reported with a reason.
668
+ */
669
+ async transferProspects(campaignId, request) {
670
+ return this.http.post(
671
+ `/campaigns/${encodeURIComponent(campaignId)}/prospects/transfer`,
672
+ request
673
+ );
674
+ }
660
675
  /**
661
676
  * Remove a prospect from a campaign.
662
677
  */
@@ -3107,6 +3122,59 @@ class ResponsesResource {
3107
3122
  throw new ValidationError("maxCommentsPerPost must be between 1 and 100");
3108
3123
  }
3109
3124
  }
3125
+ _validateCompetitorRepEngagementParams(params) {
3126
+ const company = this._getParamValue(params, "company", "company");
3127
+ const competitors = this._getParamValue(params, "competitors", "competitors");
3128
+ const engagementTypes = this._getParamValue(
3129
+ params,
3130
+ "engagementTypes",
3131
+ "engagement_types"
3132
+ );
3133
+ const hasCompany = typeof company === "string" && company.trim().length > 0;
3134
+ const hasCompetitors = Array.isArray(competitors) && competitors.length > 0;
3135
+ if (hasCompany === hasCompetitors) {
3136
+ throw new ValidationError(
3137
+ "Provide exactly one of `company` or `competitors` for competitor_rep_engagement."
3138
+ );
3139
+ }
3140
+ if (engagementTypes !== void 0) {
3141
+ if (!Array.isArray(engagementTypes) || engagementTypes.length === 0) {
3142
+ throw new ValidationError("engagementTypes must contain at least one value");
3143
+ }
3144
+ const validTypes = ["reactor", "commenter"];
3145
+ for (const type of engagementTypes) {
3146
+ if (!validTypes.includes(type)) {
3147
+ throw new ValidationError(
3148
+ `Invalid engagementTypes value: ${String(type)}. Expected 'reactor' and/or 'commenter'.`
3149
+ );
3150
+ }
3151
+ }
3152
+ }
3153
+ const limit = this._getParamValue(params, "limit", "limit");
3154
+ if (limit !== void 0 && (limit < 1 || limit > 1e3)) {
3155
+ throw new ValidationError("limit must be between 1 and 1000 for competitor_rep_engagement");
3156
+ }
3157
+ const maxCompetitors = this._getParamValue(params, "maxCompetitors", "max_competitors");
3158
+ if (maxCompetitors !== void 0 && (maxCompetitors < 1 || maxCompetitors > 50)) {
3159
+ throw new ValidationError("maxCompetitors must be between 1 and 50");
3160
+ }
3161
+ const maxRepsPerCompetitor = this._getParamValue(
3162
+ params,
3163
+ "maxRepsPerCompetitor",
3164
+ "max_reps_per_competitor"
3165
+ );
3166
+ if (maxRepsPerCompetitor !== void 0 && (maxRepsPerCompetitor < 1 || maxRepsPerCompetitor > 100)) {
3167
+ throw new ValidationError("maxRepsPerCompetitor must be between 1 and 100");
3168
+ }
3169
+ const maxEngagementsPerRep = this._getParamValue(
3170
+ params,
3171
+ "maxEngagementsPerRep",
3172
+ "max_engagements_per_rep"
3173
+ );
3174
+ if (maxEngagementsPerRep !== void 0 && (maxEngagementsPerRep < 1 || maxEngagementsPerRep > 1e3)) {
3175
+ throw new ValidationError("maxEngagementsPerRep must be between 1 and 1000");
3176
+ }
3177
+ }
3110
3178
  _validateCriteriaParams(params, specializedAgent) {
3111
3179
  if (!params)
3112
3180
  return;
@@ -3207,6 +3275,8 @@ class ResponsesResource {
3207
3275
  }
3208
3276
  if (specializedAgent === "competitor_post_engagement")
3209
3277
  this._validateCompetitorPostEngagementParams(rawParams);
3278
+ if (specializedAgent === "competitor_rep_engagement")
3279
+ this._validateCompetitorRepEngagementParams(rawParams);
3210
3280
  }
3211
3281
  _validateFileReference(uri) {
3212
3282
  if (uri.startsWith("artifact_"))
@@ -3542,6 +3612,70 @@ class ResponsesResource {
3542
3612
  request.specializedAgentParams = params;
3543
3613
  return this.create(request);
3544
3614
  }
3615
+ /**
3616
+ * Find a competitor's sales reps and surface the AUTHORS of the LinkedIn posts
3617
+ * those reps engage with — i.e. the prospects the competitor is actively
3618
+ * selling to. The INVERSE of {@link competitorPostEngagement}.
3619
+ *
3620
+ * **Discovery mode** — pass `company`: ReAct discovers competitors, then crawls
3621
+ * each one's reps and harvests their outgoing engagement.
3622
+ *
3623
+ * **Explicit mode** — pass `competitors`: skips discovery, uses your list.
3624
+ *
3625
+ * Requires `FIBER_API_KEY` + `CRUSTDATA_API_KEY`.
3626
+ *
3627
+ * @param query - Persona prompt for the prospect-authors (e.g. "VP Eng at AI-native startups…")
3628
+ * @param options - Exactly one of `company` or `competitors` is required
3629
+ * @returns Response; poll with `get()` then read `structuredResponse` as
3630
+ * {@link CompetitorRepEngagementOutput}. See `src/types/competitor-rep-engagement.ts`
3631
+ * for the full agent reference (pipeline, API keys, engagementData shape).
3632
+ */
3633
+ async competitorRepEngagement(query, options) {
3634
+ const hasCompany = typeof options.company === "string" && options.company.trim().length > 0;
3635
+ const hasCompetitors = Array.isArray(options.competitors) && options.competitors.length > 0;
3636
+ if (hasCompany === hasCompetitors) {
3637
+ throw new ValidationError(
3638
+ "Provide exactly one of `company` or `competitors` for competitorRepEngagement."
3639
+ );
3640
+ }
3641
+ const request = {
3642
+ messages: [{ role: "user", content: query }],
3643
+ specializedAgent: "competitor_rep_engagement"
3644
+ };
3645
+ const params = {};
3646
+ if (options.company)
3647
+ params.company = options.company;
3648
+ if (options.competitors)
3649
+ params.competitors = options.competitors;
3650
+ if (options.companyContext)
3651
+ params.companyContext = options.companyContext;
3652
+ if (options.companyExamples)
3653
+ params.companyExamples = options.companyExamples;
3654
+ if (options.limit !== void 0)
3655
+ params.limit = options.limit;
3656
+ if (options.postsDateRange)
3657
+ params.postsDateRange = options.postsDateRange;
3658
+ if (options.engagementTypes)
3659
+ params.engagementTypes = options.engagementTypes;
3660
+ if (options.repTitles)
3661
+ params.repTitles = options.repTitles;
3662
+ if (options.maxRepsPerCompetitor !== void 0)
3663
+ params.maxRepsPerCompetitor = options.maxRepsPerCompetitor;
3664
+ if (options.maxEngagementsPerRep !== void 0)
3665
+ params.maxEngagementsPerRep = options.maxEngagementsPerRep;
3666
+ if (options.restrictEngagementToTenure !== void 0)
3667
+ params.restrictEngagementToTenure = options.restrictEngagementToTenure;
3668
+ if (options.excludeCompetitorEmployees !== void 0)
3669
+ params.excludeCompetitorEmployees = options.excludeCompetitorEmployees;
3670
+ if (options.expandExclusionViaDiscovery !== void 0)
3671
+ params.expandExclusionViaDiscovery = options.expandExclusionViaDiscovery;
3672
+ if (options.maxCompetitors !== void 0)
3673
+ params.maxCompetitors = options.maxCompetitors;
3674
+ if (options.thoroughEnrichment !== void 0)
3675
+ params.thoroughEnrichment = options.thoroughEnrichment;
3676
+ request.specializedAgentParams = params;
3677
+ return this.create(request);
3678
+ }
3545
3679
  }
3546
3680
 
3547
3681
  class SequencesResource {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lumnisai",
3
3
  "type": "module",
4
- "version": "0.5.21",
4
+ "version": "0.5.23",
5
5
  "description": "Official Node.js SDK for the Lumnis AI API",
6
6
  "author": "Lumnis AI",
7
7
  "license": "MIT",