@the_ro_show/agent-ads-sdk 0.4.2 → 0.4.3

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.d.mts CHANGED
@@ -548,6 +548,127 @@ declare class TimeoutError extends AttentionMarketError {
548
548
  constructor(message?: string);
549
549
  }
550
550
 
551
+ /**
552
+ * Natural ad formatting utilities
553
+ *
554
+ * Transforms ad copy to feel more conversational while preserving
555
+ * all tracking data and disclosure requirements.
556
+ */
557
+
558
+ interface NaturalFormatOptions {
559
+ /**
560
+ * Tone/style for the formatted text
561
+ * - 'conversational': Friendly, natural language
562
+ * - 'helpful': Informative assistant tone
563
+ * - 'direct': Clear and concise
564
+ */
565
+ style?: 'conversational' | 'helpful' | 'direct';
566
+ /**
567
+ * Optional user context to make formatting more relevant
568
+ * Example: "User is looking for estate planning help"
569
+ */
570
+ userContext?: string;
571
+ /**
572
+ * Maximum length for formatted text (characters)
573
+ * Will truncate gracefully if needed
574
+ */
575
+ maxLength?: number;
576
+ /**
577
+ * Whether to include the disclosure inline
578
+ * Default: true (always show sponsored label)
579
+ */
580
+ includeDisclosure?: boolean;
581
+ }
582
+ interface FormattedAd {
583
+ /**
584
+ * Naturally formatted text suitable for conversation
585
+ */
586
+ text: string;
587
+ /**
588
+ * Call-to-action text
589
+ */
590
+ cta: string;
591
+ /**
592
+ * Action URL (preserved from original ad)
593
+ */
594
+ actionUrl: string;
595
+ /**
596
+ * Tracking data (preserved from original ad)
597
+ * IMPORTANT: Pass this to trackClick() when user clicks
598
+ */
599
+ tracking: {
600
+ eventId: string;
601
+ trackingToken: string;
602
+ decisionId: string;
603
+ };
604
+ /**
605
+ * Disclosure information (preserved from original ad)
606
+ */
607
+ disclosure: {
608
+ label: string;
609
+ sponsorName: string;
610
+ };
611
+ }
612
+ /**
613
+ * Format an ad unit into natural conversational text.
614
+ * Preserves all tracking data and disclosure requirements.
615
+ *
616
+ * @example
617
+ * ```typescript
618
+ * const ad = await client.decide({...});
619
+ * const formatted = formatNatural(ad, {
620
+ * style: 'conversational',
621
+ * userContext: "User needs estate planning help"
622
+ * });
623
+ *
624
+ * console.log(formatted.text);
625
+ * // "I found a service that might help: [Title]. [Body]"
626
+ *
627
+ * // When user clicks, tracking still works:
628
+ * await client.trackClick({
629
+ * event_id: formatted.tracking.eventId,
630
+ * tracking_token: formatted.tracking.trackingToken
631
+ * });
632
+ * ```
633
+ */
634
+ declare function formatNatural(ad: AdUnit, options?: NaturalFormatOptions): FormattedAd;
635
+ /**
636
+ * Extract just the essential info from an ad for inline mentions.
637
+ * Useful when you want to reference an ad without showing the full text.
638
+ *
639
+ * @example
640
+ * ```typescript
641
+ * const mention = formatInlineMention(ad);
642
+ * console.log(`You might want to check out ${mention.text}`);
643
+ * // "You might want to check out Estate Planning Services (Sponsored)"
644
+ * ```
645
+ */
646
+ declare function formatInlineMention(ad: AdUnit): FormattedAd;
647
+ /**
648
+ * Validate that an ad fits within UI constraints.
649
+ * Helps developers check if ad will display correctly before showing it.
650
+ *
651
+ * @example
652
+ * ```typescript
653
+ * const validation = validateAdFits(ad, {
654
+ * maxTitleChars: 60,
655
+ * maxBodyChars: 200
656
+ * });
657
+ *
658
+ * if (!validation.fits) {
659
+ * console.log('Ad too long:', validation.violations);
660
+ * }
661
+ * ```
662
+ */
663
+ declare function validateAdFits(ad: AdUnit, constraints: {
664
+ maxTitleChars?: number;
665
+ maxBodyChars?: number;
666
+ maxCtaChars?: number;
667
+ }): {
668
+ fits: boolean;
669
+ violations: string[];
670
+ };
671
+
551
672
  /**
552
673
  * Taxonomy helper utilities for AttentionMarket SDK
553
674
  * Helps with building, validating, and working with the 4-tier taxonomy system
@@ -705,4 +826,4 @@ declare function getVertical(taxonomy: string): string | null;
705
826
  */
706
827
  declare function suggestTaxonomies(query: string): string[];
707
828
 
708
- export { type APIError, APIRequestError, type AdScore, type AdUnit, type AgentSignupRequest, type AgentSignupResponse, AttentionMarketClient, AttentionMarketError, type Constraints, type Context, type CreateClickEventParams, type CreateImpressionEventParams, type CreateOpportunityParams, type DecideFromContextRequest, type DecideRequest, type DecideResponse, type Disclosure, type EventIngestRequest, type EventIngestResponse, type EventType, type Intent, MockAttentionMarketClient, type MockClientConfig, NetworkError, type Opportunity, type ParsedTaxonomy, type Placement, type PlacementType, type PolicyResponse, type Privacy, type SDKConfig, type SanitizeURLOptions, type SponsoredSuggestion, type SponsoredTool, type TaxonomyIntent, TimeoutError, type ToolCall, type Tracking, buildTaxonomy, createClickEvent, createImpressionEvent, createOpportunity, detectIntent, escapeHTML, generateTimestamp, generateUUID, getBaseTaxonomy, getVertical, isValidTaxonomy, matchesTaxonomy, parseTaxonomy, sanitizeURL, suggestTaxonomies };
829
+ export { type APIError, APIRequestError, type AdScore, type AdUnit, type AgentSignupRequest, type AgentSignupResponse, AttentionMarketClient, AttentionMarketError, type Constraints, type Context, type CreateClickEventParams, type CreateImpressionEventParams, type CreateOpportunityParams, type DecideFromContextRequest, type DecideRequest, type DecideResponse, type Disclosure, type EventIngestRequest, type EventIngestResponse, type EventType, type FormattedAd, type Intent, MockAttentionMarketClient, type MockClientConfig, type NaturalFormatOptions, NetworkError, type Opportunity, type ParsedTaxonomy, type Placement, type PlacementType, type PolicyResponse, type Privacy, type SDKConfig, type SanitizeURLOptions, type SponsoredSuggestion, type SponsoredTool, type TaxonomyIntent, TimeoutError, type ToolCall, type Tracking, buildTaxonomy, createClickEvent, createImpressionEvent, createOpportunity, detectIntent, escapeHTML, formatInlineMention, formatNatural, generateTimestamp, generateUUID, getBaseTaxonomy, getVertical, isValidTaxonomy, matchesTaxonomy, parseTaxonomy, sanitizeURL, suggestTaxonomies, validateAdFits };
package/dist/index.d.ts CHANGED
@@ -548,6 +548,127 @@ declare class TimeoutError extends AttentionMarketError {
548
548
  constructor(message?: string);
549
549
  }
550
550
 
551
+ /**
552
+ * Natural ad formatting utilities
553
+ *
554
+ * Transforms ad copy to feel more conversational while preserving
555
+ * all tracking data and disclosure requirements.
556
+ */
557
+
558
+ interface NaturalFormatOptions {
559
+ /**
560
+ * Tone/style for the formatted text
561
+ * - 'conversational': Friendly, natural language
562
+ * - 'helpful': Informative assistant tone
563
+ * - 'direct': Clear and concise
564
+ */
565
+ style?: 'conversational' | 'helpful' | 'direct';
566
+ /**
567
+ * Optional user context to make formatting more relevant
568
+ * Example: "User is looking for estate planning help"
569
+ */
570
+ userContext?: string;
571
+ /**
572
+ * Maximum length for formatted text (characters)
573
+ * Will truncate gracefully if needed
574
+ */
575
+ maxLength?: number;
576
+ /**
577
+ * Whether to include the disclosure inline
578
+ * Default: true (always show sponsored label)
579
+ */
580
+ includeDisclosure?: boolean;
581
+ }
582
+ interface FormattedAd {
583
+ /**
584
+ * Naturally formatted text suitable for conversation
585
+ */
586
+ text: string;
587
+ /**
588
+ * Call-to-action text
589
+ */
590
+ cta: string;
591
+ /**
592
+ * Action URL (preserved from original ad)
593
+ */
594
+ actionUrl: string;
595
+ /**
596
+ * Tracking data (preserved from original ad)
597
+ * IMPORTANT: Pass this to trackClick() when user clicks
598
+ */
599
+ tracking: {
600
+ eventId: string;
601
+ trackingToken: string;
602
+ decisionId: string;
603
+ };
604
+ /**
605
+ * Disclosure information (preserved from original ad)
606
+ */
607
+ disclosure: {
608
+ label: string;
609
+ sponsorName: string;
610
+ };
611
+ }
612
+ /**
613
+ * Format an ad unit into natural conversational text.
614
+ * Preserves all tracking data and disclosure requirements.
615
+ *
616
+ * @example
617
+ * ```typescript
618
+ * const ad = await client.decide({...});
619
+ * const formatted = formatNatural(ad, {
620
+ * style: 'conversational',
621
+ * userContext: "User needs estate planning help"
622
+ * });
623
+ *
624
+ * console.log(formatted.text);
625
+ * // "I found a service that might help: [Title]. [Body]"
626
+ *
627
+ * // When user clicks, tracking still works:
628
+ * await client.trackClick({
629
+ * event_id: formatted.tracking.eventId,
630
+ * tracking_token: formatted.tracking.trackingToken
631
+ * });
632
+ * ```
633
+ */
634
+ declare function formatNatural(ad: AdUnit, options?: NaturalFormatOptions): FormattedAd;
635
+ /**
636
+ * Extract just the essential info from an ad for inline mentions.
637
+ * Useful when you want to reference an ad without showing the full text.
638
+ *
639
+ * @example
640
+ * ```typescript
641
+ * const mention = formatInlineMention(ad);
642
+ * console.log(`You might want to check out ${mention.text}`);
643
+ * // "You might want to check out Estate Planning Services (Sponsored)"
644
+ * ```
645
+ */
646
+ declare function formatInlineMention(ad: AdUnit): FormattedAd;
647
+ /**
648
+ * Validate that an ad fits within UI constraints.
649
+ * Helps developers check if ad will display correctly before showing it.
650
+ *
651
+ * @example
652
+ * ```typescript
653
+ * const validation = validateAdFits(ad, {
654
+ * maxTitleChars: 60,
655
+ * maxBodyChars: 200
656
+ * });
657
+ *
658
+ * if (!validation.fits) {
659
+ * console.log('Ad too long:', validation.violations);
660
+ * }
661
+ * ```
662
+ */
663
+ declare function validateAdFits(ad: AdUnit, constraints: {
664
+ maxTitleChars?: number;
665
+ maxBodyChars?: number;
666
+ maxCtaChars?: number;
667
+ }): {
668
+ fits: boolean;
669
+ violations: string[];
670
+ };
671
+
551
672
  /**
552
673
  * Taxonomy helper utilities for AttentionMarket SDK
553
674
  * Helps with building, validating, and working with the 4-tier taxonomy system
@@ -705,4 +826,4 @@ declare function getVertical(taxonomy: string): string | null;
705
826
  */
706
827
  declare function suggestTaxonomies(query: string): string[];
707
828
 
708
- export { type APIError, APIRequestError, type AdScore, type AdUnit, type AgentSignupRequest, type AgentSignupResponse, AttentionMarketClient, AttentionMarketError, type Constraints, type Context, type CreateClickEventParams, type CreateImpressionEventParams, type CreateOpportunityParams, type DecideFromContextRequest, type DecideRequest, type DecideResponse, type Disclosure, type EventIngestRequest, type EventIngestResponse, type EventType, type Intent, MockAttentionMarketClient, type MockClientConfig, NetworkError, type Opportunity, type ParsedTaxonomy, type Placement, type PlacementType, type PolicyResponse, type Privacy, type SDKConfig, type SanitizeURLOptions, type SponsoredSuggestion, type SponsoredTool, type TaxonomyIntent, TimeoutError, type ToolCall, type Tracking, buildTaxonomy, createClickEvent, createImpressionEvent, createOpportunity, detectIntent, escapeHTML, generateTimestamp, generateUUID, getBaseTaxonomy, getVertical, isValidTaxonomy, matchesTaxonomy, parseTaxonomy, sanitizeURL, suggestTaxonomies };
829
+ export { type APIError, APIRequestError, type AdScore, type AdUnit, type AgentSignupRequest, type AgentSignupResponse, AttentionMarketClient, AttentionMarketError, type Constraints, type Context, type CreateClickEventParams, type CreateImpressionEventParams, type CreateOpportunityParams, type DecideFromContextRequest, type DecideRequest, type DecideResponse, type Disclosure, type EventIngestRequest, type EventIngestResponse, type EventType, type FormattedAd, type Intent, MockAttentionMarketClient, type MockClientConfig, type NaturalFormatOptions, NetworkError, type Opportunity, type ParsedTaxonomy, type Placement, type PlacementType, type PolicyResponse, type Privacy, type SDKConfig, type SanitizeURLOptions, type SponsoredSuggestion, type SponsoredTool, type TaxonomyIntent, TimeoutError, type ToolCall, type Tracking, buildTaxonomy, createClickEvent, createImpressionEvent, createOpportunity, detectIntent, escapeHTML, formatInlineMention, formatNatural, generateTimestamp, generateUUID, getBaseTaxonomy, getVertical, isValidTaxonomy, matchesTaxonomy, parseTaxonomy, sanitizeURL, suggestTaxonomies, validateAdFits };
package/dist/index.js CHANGED
@@ -32,6 +32,8 @@ __export(index_exports, {
32
32
  createOpportunity: () => createOpportunity,
33
33
  detectIntent: () => detectIntent,
34
34
  escapeHTML: () => escapeHTML,
35
+ formatInlineMention: () => formatInlineMention,
36
+ formatNatural: () => formatNatural,
35
37
  generateTimestamp: () => generateTimestamp,
36
38
  generateUUID: () => generateUUID,
37
39
  getBaseTaxonomy: () => getBaseTaxonomy,
@@ -40,7 +42,8 @@ __export(index_exports, {
40
42
  matchesTaxonomy: () => matchesTaxonomy,
41
43
  parseTaxonomy: () => parseTaxonomy,
42
44
  sanitizeURL: () => sanitizeURL,
43
- suggestTaxonomies: () => suggestTaxonomies
45
+ suggestTaxonomies: () => suggestTaxonomies,
46
+ validateAdFits: () => validateAdFits
44
47
  });
45
48
  module.exports = __toCommonJS(index_exports);
46
49
 
@@ -807,6 +810,128 @@ var MockAttentionMarketClient = class {
807
810
  }
808
811
  };
809
812
 
813
+ // src/formatting.ts
814
+ function formatNatural(ad, options = {}) {
815
+ if (ad.unit_type !== "sponsored_suggestion") {
816
+ throw new Error("formatNatural() currently only supports sponsored_suggestion ad units");
817
+ }
818
+ const suggestion = ad.suggestion;
819
+ const style = options.style || "conversational";
820
+ const includeDisclosure = options.includeDisclosure !== false;
821
+ let text = "";
822
+ switch (style) {
823
+ case "conversational":
824
+ text = buildConversationalText(suggestion, options.userContext);
825
+ break;
826
+ case "helpful":
827
+ text = buildHelpfulText(suggestion, options.userContext);
828
+ break;
829
+ case "direct":
830
+ text = buildDirectText(suggestion);
831
+ break;
832
+ }
833
+ if (includeDisclosure) {
834
+ text = `${text}
835
+
836
+ _${ad.disclosure.label}_ by ${ad.disclosure.sponsor_name}`;
837
+ }
838
+ if (options.maxLength && text.length > options.maxLength) {
839
+ text = truncateGracefully(text, options.maxLength);
840
+ }
841
+ return {
842
+ text,
843
+ cta: suggestion.cta,
844
+ actionUrl: suggestion.action_url,
845
+ tracking: {
846
+ eventId: ad.unit_id,
847
+ // Use unit_id as event_id
848
+ trackingToken: ad.tracking.token,
849
+ decisionId: ad.unit_id
850
+ // Use unit_id as decision_id fallback
851
+ },
852
+ disclosure: {
853
+ label: ad.disclosure.label,
854
+ sponsorName: ad.disclosure.sponsor_name
855
+ }
856
+ };
857
+ }
858
+ function buildConversationalText(ad, userContext) {
859
+ const intro = userContext ? `Based on what you mentioned, I found something that might help: ` : `I found something that might be useful: `;
860
+ return `${intro}**${ad.title}**. ${ad.body}`;
861
+ }
862
+ function buildHelpfulText(ad, userContext) {
863
+ const intro = userContext ? `For your situation, here's a relevant service: ` : `Here's a service you might find helpful: `;
864
+ return `${intro}**${ad.title}** \u2014 ${ad.body}`;
865
+ }
866
+ function buildDirectText(ad) {
867
+ return `**${ad.title}**
868
+ ${ad.body}`;
869
+ }
870
+ function truncateGracefully(text, maxLength) {
871
+ if (text.length <= maxLength) {
872
+ return text;
873
+ }
874
+ const truncated = text.substring(0, maxLength);
875
+ const lastPeriod = truncated.lastIndexOf(".");
876
+ const lastQuestion = truncated.lastIndexOf("?");
877
+ const lastExclamation = truncated.lastIndexOf("!");
878
+ const sentenceEnd = Math.max(lastPeriod, lastQuestion, lastExclamation);
879
+ if (sentenceEnd > maxLength * 0.7) {
880
+ return text.substring(0, sentenceEnd + 1);
881
+ }
882
+ const lastSpace = truncated.lastIndexOf(" ");
883
+ if (lastSpace > 0) {
884
+ return truncated.substring(0, lastSpace) + "...";
885
+ }
886
+ return truncated.substring(0, maxLength - 3) + "...";
887
+ }
888
+ function formatInlineMention(ad) {
889
+ if (ad.unit_type !== "sponsored_suggestion") {
890
+ throw new Error("formatInlineMention() currently only supports sponsored_suggestion ad units");
891
+ }
892
+ const suggestion = ad.suggestion;
893
+ return {
894
+ text: `${suggestion.title} (${ad.disclosure.label})`,
895
+ cta: suggestion.cta,
896
+ actionUrl: suggestion.action_url,
897
+ tracking: {
898
+ eventId: ad.unit_id,
899
+ trackingToken: ad.tracking.token,
900
+ decisionId: ad.unit_id
901
+ },
902
+ disclosure: {
903
+ label: ad.disclosure.label,
904
+ sponsorName: ad.disclosure.sponsor_name
905
+ }
906
+ };
907
+ }
908
+ function validateAdFits(ad, constraints) {
909
+ if (ad.unit_type !== "sponsored_suggestion") {
910
+ return { fits: true, violations: [] };
911
+ }
912
+ const suggestion = ad.suggestion;
913
+ const violations = [];
914
+ if (constraints.maxTitleChars && suggestion.title.length > constraints.maxTitleChars) {
915
+ violations.push(
916
+ `Title too long: ${suggestion.title.length} chars (max ${constraints.maxTitleChars})`
917
+ );
918
+ }
919
+ if (constraints.maxBodyChars && suggestion.body.length > constraints.maxBodyChars) {
920
+ violations.push(
921
+ `Body too long: ${suggestion.body.length} chars (max ${constraints.maxBodyChars})`
922
+ );
923
+ }
924
+ if (constraints.maxCtaChars && suggestion.cta.length > constraints.maxCtaChars) {
925
+ violations.push(
926
+ `CTA too long: ${suggestion.cta.length} chars (max ${constraints.maxCtaChars})`
927
+ );
928
+ }
929
+ return {
930
+ fits: violations.length === 0,
931
+ violations
932
+ };
933
+ }
934
+
810
935
  // src/taxonomy-utils.ts
811
936
  function buildTaxonomy(vertical, category, subcategory, intent) {
812
937
  const parts = [vertical, category, subcategory];
@@ -949,6 +1074,8 @@ function suggestTaxonomies(query) {
949
1074
  createOpportunity,
950
1075
  detectIntent,
951
1076
  escapeHTML,
1077
+ formatInlineMention,
1078
+ formatNatural,
952
1079
  generateTimestamp,
953
1080
  generateUUID,
954
1081
  getBaseTaxonomy,
@@ -957,6 +1084,7 @@ function suggestTaxonomies(query) {
957
1084
  matchesTaxonomy,
958
1085
  parseTaxonomy,
959
1086
  sanitizeURL,
960
- suggestTaxonomies
1087
+ suggestTaxonomies,
1088
+ validateAdFits
961
1089
  });
962
1090
  //# sourceMappingURL=index.js.map