lumnisai 0.5.45 → 0.5.46

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
@@ -3250,6 +3250,9 @@ const ENGAGEMENT_ACTIVITIES = [
3250
3250
  "comments",
3251
3251
  "authored_posts"
3252
3252
  ];
3253
+ const MAX_SIGNAL_CONTEXT_CHARS = 4e3;
3254
+ const MAX_CONTENT_INTELLIGENCE_COMPETITORS = 5;
3255
+ const MAX_CONTENT_INTELLIGENCE_COMPETITOR_CHARS = 200;
3253
3256
  class ResponsesResource {
3254
3257
  constructor(http) {
3255
3258
  this.http = http;
@@ -3499,12 +3502,16 @@ class ResponsesResource {
3499
3502
  }
3500
3503
  seen.add(name);
3501
3504
  for (const key of Object.keys(entry)) {
3502
- if (key !== "name" && key !== "settings") {
3505
+ if (key !== "name" && key !== "settings" && key !== "context") {
3503
3506
  throw new ValidationError(
3504
- `Unknown signalDefinitions field '${key}'. Each entry accepts only name and settings.`
3507
+ `Unknown signalDefinitions field '${key}'. Each entry accepts only name, settings, and context.`
3505
3508
  );
3506
3509
  }
3507
3510
  }
3511
+ this._validateContextBrief(
3512
+ this._getParamValue(entry, "context", "context"),
3513
+ `signalDefinitions '${name}' context`
3514
+ );
3508
3515
  this._validateSignalSettings(
3509
3516
  name,
3510
3517
  this._getParamValue(entry, "settings", "settings")
@@ -3545,6 +3552,14 @@ class ResponsesResource {
3545
3552
  "postsDateRange"
3546
3553
  );
3547
3554
  }
3555
+ _validateContextBrief(value, field) {
3556
+ if (value === void 0 || value === null)
3557
+ return;
3558
+ if (typeof value !== "string")
3559
+ throw new ValidationError(`${field} must be plain text`);
3560
+ if ([...value.trim()].length > MAX_SIGNAL_CONTEXT_CHARS)
3561
+ throw new ValidationError(`${field} must be at most ${MAX_SIGNAL_CONTEXT_CHARS} characters`);
3562
+ }
3548
3563
  _validateCompetitorRepEngagementParams(params) {
3549
3564
  const company = this._getParamValue(params, "company", "company");
3550
3565
  const competitors = this._getParamValue(params, "competitors", "competitors");
@@ -3627,6 +3642,91 @@ class ResponsesResource {
3627
3642
  }
3628
3643
  }
3629
3644
  }
3645
+ const rawCompetitors = this._getParamValue(params, "competitors", "competitors");
3646
+ const competitors = this._normalizedContentIntelligenceCompetitors(rawCompetitors);
3647
+ if (competitors.length > MAX_CONTENT_INTELLIGENCE_COMPETITORS) {
3648
+ throw new ValidationError(
3649
+ `competitors must contain at most ${MAX_CONTENT_INTELLIGENCE_COMPETITORS} distinct values`
3650
+ );
3651
+ }
3652
+ const rawCompany = this._getParamValue(params, "company", "company");
3653
+ let company;
3654
+ if (rawCompany !== void 0 && rawCompany !== null) {
3655
+ if (typeof rawCompany !== "string")
3656
+ throw new ValidationError("company must be a string for content_intelligence");
3657
+ company = rawCompany.trim() || void 0;
3658
+ if (company && [...company].length > MAX_CONTENT_INTELLIGENCE_COMPETITOR_CHARS) {
3659
+ throw new ValidationError(
3660
+ `company must be at most ${MAX_CONTENT_INTELLIGENCE_COMPETITOR_CHARS} characters`
3661
+ );
3662
+ }
3663
+ }
3664
+ const normalizedCompany = company?.toLowerCase();
3665
+ if (normalizedCompany && competitors.some((competitor) => competitor.toLowerCase() === normalizedCompany)) {
3666
+ throw new ValidationError(
3667
+ `company '${company}' is also listed in competitors; name it on one side only`
3668
+ );
3669
+ }
3670
+ for (const [camel, snake] of [
3671
+ ["includeCompanyPosts", "include_company_posts"],
3672
+ ["includeExecPosts", "include_exec_posts"]
3673
+ ]) {
3674
+ const value = this._getParamValue(params, camel, snake);
3675
+ if (value !== void 0 && typeof value !== "boolean")
3676
+ throw new ValidationError(`${camel} must be true or false`);
3677
+ }
3678
+ const includeCompanyPosts = this._getParamValue(
3679
+ params,
3680
+ "includeCompanyPosts",
3681
+ "include_company_posts"
3682
+ );
3683
+ const includeExecPosts = this._getParamValue(
3684
+ params,
3685
+ "includeExecPosts",
3686
+ "include_exec_posts"
3687
+ );
3688
+ if (competitors.length > 0 && includeCompanyPosts === false && includeExecPosts === false) {
3689
+ throw new ValidationError(
3690
+ "competitors were provided but includeCompanyPosts and includeExecPosts are both false"
3691
+ );
3692
+ }
3693
+ const execTitles = this._getParamValue(params, "execTitles", "exec_titles");
3694
+ if (execTitles !== void 0 && (!Array.isArray(execTitles) || execTitles.some((title) => typeof title !== "string"))) {
3695
+ throw new ValidationError("execTitles must be an array of strings");
3696
+ }
3697
+ const maxExecsPerTarget = this._getParamValue(
3698
+ params,
3699
+ "maxExecsPerTarget",
3700
+ "max_execs_per_target"
3701
+ );
3702
+ if (maxExecsPerTarget !== void 0 && (!Number.isInteger(maxExecsPerTarget) || maxExecsPerTarget < 1 || maxExecsPerTarget > 20)) {
3703
+ throw new ValidationError("maxExecsPerTarget must be an integer between 1 and 20");
3704
+ }
3705
+ }
3706
+ _normalizedContentIntelligenceCompetitors(value) {
3707
+ if (value === void 0 || value === null)
3708
+ return [];
3709
+ const values = typeof value === "string" ? [value] : value;
3710
+ if (!Array.isArray(values) || values.some((entry) => typeof entry !== "string"))
3711
+ throw new ValidationError("competitors must be an array of strings");
3712
+ const seen = /* @__PURE__ */ new Set();
3713
+ const normalized = [];
3714
+ for (const entry of values) {
3715
+ const competitor = entry.trim();
3716
+ if (!competitor)
3717
+ continue;
3718
+ if ([...competitor].length > MAX_CONTENT_INTELLIGENCE_COMPETITOR_CHARS) {
3719
+ throw new ValidationError(
3720
+ `each competitor must be at most ${MAX_CONTENT_INTELLIGENCE_COMPETITOR_CHARS} characters`
3721
+ );
3722
+ }
3723
+ const key = competitor.toLowerCase();
3724
+ if (!seen.has(key)) {
3725
+ seen.add(key);
3726
+ normalized.push(competitor);
3727
+ }
3728
+ }
3729
+ return normalized;
3630
3730
  }
3631
3731
  _validateEngagementExpansionParams(params) {
3632
3732
  const expandFromResponse = this._getParamValue(
@@ -4317,6 +4417,10 @@ class ResponsesResource {
4317
4417
  * `reusePackageFrom` to re-cook a saved package without collecting again.
4318
4418
  * `companyContext` and `contentDirection` steer post ideas only; collection,
4319
4419
  * curation, and engagement analysis remain an unbiased read of the audience.
4420
+ * Add `competitors` to receive a separate publication report over the same
4421
+ * window; competitor posts never enter the audience package or metrics. Add
4422
+ * `company` to put the caller's own publication activity beside those
4423
+ * competitors in the report.
4320
4424
  *
4321
4425
  * @param query - Natural-language description of the audience. A nonblank
4322
4426
  * message is required even when reusing a package.
@@ -4343,6 +4447,18 @@ class ResponsesResource {
4343
4447
  params.reusePackageFrom = options.reusePackageFrom;
4344
4448
  if (options.outputs !== void 0)
4345
4449
  params.outputs = options.outputs;
4450
+ if (options.competitors !== void 0)
4451
+ params.competitors = options.competitors;
4452
+ if (options.company !== void 0)
4453
+ params.company = options.company;
4454
+ if (options.includeCompanyPosts !== void 0)
4455
+ params.includeCompanyPosts = options.includeCompanyPosts;
4456
+ if (options.includeExecPosts !== void 0)
4457
+ params.includeExecPosts = options.includeExecPosts;
4458
+ if (options.execTitles !== void 0)
4459
+ params.execTitles = options.execTitles;
4460
+ if (options.maxExecsPerTarget !== void 0)
4461
+ params.maxExecsPerTarget = options.maxExecsPerTarget;
4346
4462
  return this.create({
4347
4463
  messages: [{ role: "user", content: query }],
4348
4464
  specializedAgent: "content_intelligence",