@the_ro_show/agent-ads-sdk 0.16.1 → 0.17.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/README.md CHANGED
@@ -46,6 +46,35 @@ if (ad) {
46
46
  }
47
47
  ```
48
48
 
49
+ ## How You Earn Money
50
+
51
+ AttentionMarket pays you when users **click** sponsored content. It's that simple.
52
+
53
+ ### Revenue Formula
54
+ ```
55
+ Your Earnings = Clicks × Payout Per Click
56
+ ```
57
+
58
+ Every response shows exactly what you'll earn:
59
+ ```typescript
60
+ {
61
+ "payout": 250, // You earn $2.50 when clicked
62
+ "click_url": "https://...",
63
+ "creative": { title: "...", body: "..." }
64
+ }
65
+ ```
66
+
67
+ ### Why We Track Impressions
68
+
69
+ Impressions prevent click fraud. If sponsored content wasn't shown, clicks won't generate revenue.
70
+
71
+ **Important:**
72
+ - ✅ Impressions are **required** for clicks to count
73
+ - ❌ Impressions do **NOT** generate revenue themselves
74
+ - ✅ The SDK tracks impressions automatically
75
+
76
+ Think of impressions as a receipt: "Yes, this content was actually shown to a real user."
77
+
49
78
  ## Smart Context (v0.15.1+) 🎯
50
79
 
51
80
  Improve ad relevance by 2-3x with smart context features that understand user intent better:
@@ -375,10 +404,10 @@ const ad = await client.decideFromContext({
375
404
  **Validation:** Must be a non-negative number.
376
405
 
377
406
  **Use cases:**
378
- - Premium applications: `200+` for $2+ ads only
407
+ - Premium applications: `200+` for $2+ per click only
379
408
  - High-value verticals: Filter out low-budget advertisers
380
- - Revenue targets: Ensure minimum revenue per impression
381
- - Lower fill rate tolerance: When you'd rather show nothing than a low-value ad
409
+ - Revenue targets: Ensure minimum earnings when clicked
410
+ - Lower fill rate tolerance: When you'd rather show nothing than low-value content
382
411
 
383
412
  **Trade-off:** Higher thresholds = higher revenue per ad but lower fill rate.
384
413
 
@@ -586,6 +615,122 @@ await client.track({
586
615
  });
587
616
  ```
588
617
 
618
+ ### Developer Prediction System (Bonus Earnings)
619
+
620
+ **Get paid more for accurate predictions!** After showing an ad, predict whether the user will convert. If you're right, earn a bonus:
621
+ - ✅ Correct positive prediction → **+20% bonus**
622
+ - ✅ Correct negative prediction → **+5% bonus**
623
+ - ⚠️ Wrong prediction → No bonus (but no penalty)
624
+
625
+ #### How It Works
626
+
627
+ 1. **Show the ad** to your user using `decideFromContext()`
628
+ 2. **Observe their reaction** (interested? asked questions? changed topic?)
629
+ 3. **Send feedback** with your prediction
630
+ 4. **Get bonus** 7 days later if you were right
631
+
632
+ #### Option 1: Auto-Analysis (Recommended - Easiest)
633
+
634
+ Just send the user's raw response, and our AI analyzes sentiment automatically:
635
+
636
+ ```typescript
637
+ const ad = await client.decideFromContext({
638
+ userMessage: "I need car insurance",
639
+ placement: 'sponsored_suggestion'
640
+ });
641
+
642
+ // Show ad to user...
643
+ // User responds: "Tell me more about that Geico offer!"
644
+
645
+ await client.sendFeedback({
646
+ tracking_token: ad.tracking_token,
647
+ user_response: "Tell me more about that Geico offer!",
648
+ conversation_history: [
649
+ "User: I need car insurance",
650
+ "Agent: Check out Geico...",
651
+ "User: Tell me more about that Geico offer!"
652
+ ]
653
+ });
654
+
655
+ // Our AI detects: "positive" sentiment
656
+ // You get base earnings + 20% bonus if user converts
657
+ ```
658
+
659
+ **When to use:** You want simplicity. Let our AI handle sentiment analysis.
660
+
661
+ #### Option 2: Manual Prediction (Advanced - Full Control)
662
+
663
+ Analyze sentiment yourself and send your prediction:
664
+
665
+ ```typescript
666
+ const ad = await client.decideFromContext({
667
+ userMessage: "I need car insurance",
668
+ placement: 'sponsored_suggestion'
669
+ });
670
+
671
+ // Show ad to user...
672
+ // User responds: "No thanks, I already have insurance"
673
+
674
+ // YOU analyze: User declined → predict negative
675
+ await client.sendFeedback({
676
+ tracking_token: ad.tracking_token,
677
+ reaction: 'negative', // You determine this
678
+ context: 'User already has insurance, politely declined'
679
+ });
680
+
681
+ // If user doesn't convert, you get +5% bonus
682
+ ```
683
+
684
+ **When to use:** You want full control over sentiment classification, or you have your own sentiment analysis.
685
+
686
+ #### Prediction Guidelines
687
+
688
+ **Positive** - User shows interest:
689
+ - "Tell me more!"
690
+ - "How much does it cost?"
691
+ - "Can you sign me up?"
692
+ - Asks follow-up questions
693
+
694
+ **Neutral** - Hard to tell:
695
+ - "Maybe later"
696
+ - "I'll think about it"
697
+ - No clear response
698
+ - Non-committal
699
+
700
+ **Negative** - User not interested:
701
+ - "No thanks"
702
+ - "I already have that"
703
+ - Changes topic immediately
704
+ - Explicitly declines
705
+
706
+ #### Response Format
707
+
708
+ ```typescript
709
+ {
710
+ status: 'received',
711
+ feedback_id: 'evt_abc123',
712
+ potential_bonus: '20%',
713
+ resolution_date: '2026-03-13',
714
+ message: 'Feedback recorded. Bonus will be calculated after 7-day conversion window.',
715
+
716
+ // Only in auto-analysis mode:
717
+ sentiment_detected: 'positive',
718
+ analysis_mode: 'auto'
719
+ }
720
+ ```
721
+
722
+ #### Best Practices
723
+
724
+ 1. **Submit within 24 hours** - Feedback must be sent within 24 hours of showing the ad
725
+ 2. **One prediction per ad** - You can only submit feedback once per tracking_token
726
+ 3. **Be honest** - Don't predict "positive" for everything. Our system rewards accuracy, not volume
727
+ 4. **Use context** - Include conversation history for better auto-analysis
728
+ 5. **Skip when unsure** - No feedback is better than random guessing
729
+
730
+ #### Cost of Auto-Analysis
731
+
732
+ Auto-analysis costs ~$0.0001 per request (using GPT-3.5-turbo). We absorb this cost, so it's free for you. The better accuracy and developer experience is worth it.
733
+
589
734
  ## Error Handling
590
735
 
591
736
  The SDK throws errors for invalid configurations and failed requests:
@@ -704,6 +849,15 @@ Create a simple getRelevantAd(message) function that returns ads only when relev
704
849
 
705
850
  ## Changelog
706
851
 
852
+ ### v0.17.0 (2026-03-06) - AI-Powered Feedback Analysis
853
+ - 🤖 **Auto-Analysis Mode:** Send raw user responses, our AI detects sentiment automatically
854
+ - 💰 **Bonus Earnings:** +20% for correct positive predictions, +5% for correct negative predictions
855
+ - 🔄 **Backward Compatible:** Existing manual `reaction` mode still supported
856
+ - 📊 **Conversation Context:** Include conversation history for better sentiment analysis
857
+ - ⚡ **Fast & Cheap:** GPT-3.5-turbo analysis (~$0.0001 per request, free for developers)
858
+ - 🎯 **Fallback Logic:** Defaults to 'neutral' if AI analysis fails
859
+ - 📝 **Enhanced Logging:** Track analysis_mode and sentiment_confidence in metadata
860
+
707
861
  ### v0.15.1 (2026-02-26) - Bug Fixes & Security
708
862
  - 🔒 Fixed session leak - sessionId now request-scoped, not instance-scoped
709
863
  - 🛡️ Added comprehensive input validation and sanitization
package/dist/index.d.mts CHANGED
@@ -294,44 +294,63 @@ interface EventIngestRequest {
294
294
  interface EventIngestResponse {
295
295
  accepted: boolean;
296
296
  }
297
- /**
298
- * Sentiment types detected by backend AI analysis.
299
- *
300
- * - positive: User is interested/engaged (earn +15% if converts, -5% if not)
301
- * - neutral: User is indifferent (no bonus/penalty, data only)
302
- * - negative: User disliked the ad (no penalty, data only)
303
- */
304
- type FeedbackSentiment = 'positive' | 'neutral' | 'negative';
305
297
  /**
306
298
  * Send feedback on an ad after showing it to a user.
307
299
  *
308
- * **New in v0.11.0:** Backend analyzes sentiment automatically using AI.
309
- * Just send the user's actual response text - no need to classify it yourself.
300
+ * **Two modes available:**
310
301
  *
311
- * **Anti-Fraud:** Bonuses are deferred and validated against actual conversions.
312
- * - Correct positive prediction → +15% bonus after 7 days
313
- * - Wrong positive prediction → -5% penalty after 7 days
314
- * - Neutral/negative → no bonus/penalty (data only)
302
+ * **Auto-Analysis (Recommended):** Send the user's raw response, and our AI analyzes sentiment.
303
+ * ```typescript
304
+ * await client.sendFeedback({
305
+ * tracking_token: ad.tracking_token,
306
+ * user_response: "Tell me more about that!",
307
+ * conversation_history: ["Previous message 1", "Previous message 2"]
308
+ * });
309
+ * ```
315
310
  *
316
- * @example
311
+ * **Manual Prediction:** Analyze sentiment yourself and send the prediction.
317
312
  * ```typescript
318
313
  * await client.sendFeedback({
319
314
  * tracking_token: ad.tracking_token,
320
- * user_response: "This looks perfect! How do I sign up?",
321
- * agent_response: "Here's the signup link...",
322
- * additional_context: "User spent 2 minutes reading the offer"
315
+ * reaction: 'positive', // You determine this
316
+ * context: 'User asked follow-up questions'
323
317
  * });
324
318
  * ```
319
+ *
320
+ * **Bonuses (7-day deferred):**
321
+ * - Correct positive prediction → +20% bonus
322
+ * - Correct negative prediction → +5% bonus
323
+ * - Wrong prediction or no feedback → No bonus
325
324
  */
326
325
  interface FeedbackRequest {
327
- /** Tracking token from the ad you showed */
326
+ /** Tracking token from the ad you showed (required) */
328
327
  tracking_token: string;
329
- /** User's actual response text (required) */
330
- user_response: string;
331
- /** Your agent's response (optional, helps sentiment analysis) */
332
- agent_response?: string;
333
- /** Additional context about the interaction (optional) */
334
- additional_context?: string;
328
+ /**
329
+ * OPTION 1 (Auto-Analysis): User's actual response text.
330
+ * Our AI will analyze sentiment and determine positive/neutral/negative.
331
+ * Max 2000 characters.
332
+ */
333
+ user_response?: string;
334
+ /**
335
+ * Conversation history for better context in auto-analysis.
336
+ * We use the last 3 messages to understand the conversation flow.
337
+ */
338
+ conversation_history?: string[];
339
+ /**
340
+ * OPTION 2 (Manual): Your prediction of user interest.
341
+ * Use this if you want full control over sentiment classification.
342
+ */
343
+ reaction?: 'positive' | 'neutral' | 'negative';
344
+ /**
345
+ * Additional context about the interaction (optional, both modes).
346
+ * Max 1000 characters.
347
+ */
348
+ context?: string;
349
+ /**
350
+ * Idempotency key for safe retries (optional).
351
+ * Use the same key if retrying a failed request to avoid duplicate feedback.
352
+ */
353
+ idempotency_key?: string;
335
354
  }
336
355
  /**
337
356
  * Response from sending feedback.
@@ -340,18 +359,27 @@ interface FeedbackRequest {
340
359
  * based on whether the user actually converted.
341
360
  */
342
361
  interface FeedbackResponse {
343
- /** Whether feedback was recorded successfully */
344
- success: boolean;
345
- /** AI-detected sentiment from user response */
346
- sentiment_detected: FeedbackSentiment;
347
- /** Potential bonus if prediction is correct (not guaranteed) */
362
+ /** Status of feedback submission */
363
+ status: 'received';
364
+ /** Unique ID for this feedback event */
365
+ feedback_id: string;
366
+ /** Potential bonus if prediction is correct (20% for positive, 5% for negative) */
348
367
  potential_bonus: string;
349
- /** Potential penalty if prediction is wrong */
350
- potential_penalty: string;
351
368
  /** Explanation of the deferred bonus system */
352
369
  message: string;
353
- /** When the bonus will be resolved (7 days from now) */
370
+ /** When the bonus will be resolved (7 days from impression, YYYY-MM-DD) */
354
371
  resolution_date: string;
372
+ /**
373
+ * AI-detected sentiment (only present in auto-analysis mode).
374
+ * Shows what sentiment our AI detected from the user response.
375
+ */
376
+ sentiment_detected?: 'positive' | 'neutral' | 'negative';
377
+ /**
378
+ * Analysis mode used (only present in auto-analysis or fallback modes).
379
+ * - 'auto': AI analyzed sentiment
380
+ * - 'fallback': AI failed, defaulted to neutral
381
+ */
382
+ analysis_mode?: 'auto' | 'fallback';
355
383
  }
356
384
  interface PolicyResponse {
357
385
  version: string;
package/dist/index.d.ts CHANGED
@@ -294,44 +294,63 @@ interface EventIngestRequest {
294
294
  interface EventIngestResponse {
295
295
  accepted: boolean;
296
296
  }
297
- /**
298
- * Sentiment types detected by backend AI analysis.
299
- *
300
- * - positive: User is interested/engaged (earn +15% if converts, -5% if not)
301
- * - neutral: User is indifferent (no bonus/penalty, data only)
302
- * - negative: User disliked the ad (no penalty, data only)
303
- */
304
- type FeedbackSentiment = 'positive' | 'neutral' | 'negative';
305
297
  /**
306
298
  * Send feedback on an ad after showing it to a user.
307
299
  *
308
- * **New in v0.11.0:** Backend analyzes sentiment automatically using AI.
309
- * Just send the user's actual response text - no need to classify it yourself.
300
+ * **Two modes available:**
310
301
  *
311
- * **Anti-Fraud:** Bonuses are deferred and validated against actual conversions.
312
- * - Correct positive prediction → +15% bonus after 7 days
313
- * - Wrong positive prediction → -5% penalty after 7 days
314
- * - Neutral/negative → no bonus/penalty (data only)
302
+ * **Auto-Analysis (Recommended):** Send the user's raw response, and our AI analyzes sentiment.
303
+ * ```typescript
304
+ * await client.sendFeedback({
305
+ * tracking_token: ad.tracking_token,
306
+ * user_response: "Tell me more about that!",
307
+ * conversation_history: ["Previous message 1", "Previous message 2"]
308
+ * });
309
+ * ```
315
310
  *
316
- * @example
311
+ * **Manual Prediction:** Analyze sentiment yourself and send the prediction.
317
312
  * ```typescript
318
313
  * await client.sendFeedback({
319
314
  * tracking_token: ad.tracking_token,
320
- * user_response: "This looks perfect! How do I sign up?",
321
- * agent_response: "Here's the signup link...",
322
- * additional_context: "User spent 2 minutes reading the offer"
315
+ * reaction: 'positive', // You determine this
316
+ * context: 'User asked follow-up questions'
323
317
  * });
324
318
  * ```
319
+ *
320
+ * **Bonuses (7-day deferred):**
321
+ * - Correct positive prediction → +20% bonus
322
+ * - Correct negative prediction → +5% bonus
323
+ * - Wrong prediction or no feedback → No bonus
325
324
  */
326
325
  interface FeedbackRequest {
327
- /** Tracking token from the ad you showed */
326
+ /** Tracking token from the ad you showed (required) */
328
327
  tracking_token: string;
329
- /** User's actual response text (required) */
330
- user_response: string;
331
- /** Your agent's response (optional, helps sentiment analysis) */
332
- agent_response?: string;
333
- /** Additional context about the interaction (optional) */
334
- additional_context?: string;
328
+ /**
329
+ * OPTION 1 (Auto-Analysis): User's actual response text.
330
+ * Our AI will analyze sentiment and determine positive/neutral/negative.
331
+ * Max 2000 characters.
332
+ */
333
+ user_response?: string;
334
+ /**
335
+ * Conversation history for better context in auto-analysis.
336
+ * We use the last 3 messages to understand the conversation flow.
337
+ */
338
+ conversation_history?: string[];
339
+ /**
340
+ * OPTION 2 (Manual): Your prediction of user interest.
341
+ * Use this if you want full control over sentiment classification.
342
+ */
343
+ reaction?: 'positive' | 'neutral' | 'negative';
344
+ /**
345
+ * Additional context about the interaction (optional, both modes).
346
+ * Max 1000 characters.
347
+ */
348
+ context?: string;
349
+ /**
350
+ * Idempotency key for safe retries (optional).
351
+ * Use the same key if retrying a failed request to avoid duplicate feedback.
352
+ */
353
+ idempotency_key?: string;
335
354
  }
336
355
  /**
337
356
  * Response from sending feedback.
@@ -340,18 +359,27 @@ interface FeedbackRequest {
340
359
  * based on whether the user actually converted.
341
360
  */
342
361
  interface FeedbackResponse {
343
- /** Whether feedback was recorded successfully */
344
- success: boolean;
345
- /** AI-detected sentiment from user response */
346
- sentiment_detected: FeedbackSentiment;
347
- /** Potential bonus if prediction is correct (not guaranteed) */
362
+ /** Status of feedback submission */
363
+ status: 'received';
364
+ /** Unique ID for this feedback event */
365
+ feedback_id: string;
366
+ /** Potential bonus if prediction is correct (20% for positive, 5% for negative) */
348
367
  potential_bonus: string;
349
- /** Potential penalty if prediction is wrong */
350
- potential_penalty: string;
351
368
  /** Explanation of the deferred bonus system */
352
369
  message: string;
353
- /** When the bonus will be resolved (7 days from now) */
370
+ /** When the bonus will be resolved (7 days from impression, YYYY-MM-DD) */
354
371
  resolution_date: string;
372
+ /**
373
+ * AI-detected sentiment (only present in auto-analysis mode).
374
+ * Shows what sentiment our AI detected from the user response.
375
+ */
376
+ sentiment_detected?: 'positive' | 'neutral' | 'negative';
377
+ /**
378
+ * Analysis mode used (only present in auto-analysis or fallback modes).
379
+ * - 'auto': AI analyzed sentiment
380
+ * - 'fallback': AI failed, defaulted to neutral
381
+ */
382
+ analysis_mode?: 'auto' | 'fallback';
355
383
  }
356
384
  interface PolicyResponse {
357
385
  version: string;
package/dist/index.js CHANGED
@@ -1393,6 +1393,7 @@ var AttentionMarketClient = class {
1393
1393
  url
1394
1394
  );
1395
1395
  }
1396
+ // TODO: Add getDeveloperMetrics() method when DeveloperMetricsResponse type is defined
1396
1397
  };
1397
1398
 
1398
1399
  // src/mock-client.ts