@the_ro_show/agent-ads-sdk 0.14.2 → 0.16.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/dist/index.js CHANGED
@@ -27,7 +27,6 @@ __export(index_exports, {
27
27
  NetworkError: () => NetworkError,
28
28
  TimeoutError: () => TimeoutError,
29
29
  buildTaxonomy: () => buildTaxonomy,
30
- createClickEvent: () => createClickEvent,
31
30
  createImpressionEvent: () => createImpressionEvent,
32
31
  createOpportunity: () => createOpportunity,
33
32
  detectIntent: () => detectIntent,
@@ -247,31 +246,6 @@ function createImpressionEvent(params) {
247
246
  }
248
247
  return event;
249
248
  }
250
- function createClickEvent(params) {
251
- const event = {
252
- event_id: generateUUID(),
253
- occurred_at: params.occurred_at ?? generateTimestamp(),
254
- agent_id: params.agent_id,
255
- request_id: params.request_id,
256
- decision_id: params.decision_id,
257
- unit_id: params.unit_id,
258
- event_type: "click",
259
- tracking_token: params.tracking_token
260
- };
261
- if (params.metadata !== void 0) {
262
- event.metadata = {
263
- ...params.metadata,
264
- href: params.href,
265
- click_context: params.click_context
266
- };
267
- } else {
268
- event.metadata = {
269
- href: params.href,
270
- click_context: params.click_context
271
- };
272
- }
273
- return event;
274
- }
275
249
  var HTML_ESCAPES = {
276
250
  "&": "&",
277
251
  "<": "&lt;",
@@ -353,6 +327,172 @@ function sanitizeURL(url, options) {
353
327
  }
354
328
  }
355
329
 
330
+ // src/utils/intent-detector.ts
331
+ var INTENT_PATTERNS = {
332
+ research: [
333
+ "what is",
334
+ "how does",
335
+ "explain",
336
+ "tell me about",
337
+ "learn about",
338
+ "understand",
339
+ "guide",
340
+ "tips",
341
+ "basics",
342
+ "introduction",
343
+ "overview",
344
+ "how to"
345
+ ],
346
+ comparison: [
347
+ "vs",
348
+ "versus",
349
+ "compare",
350
+ "better than",
351
+ "difference",
352
+ "which",
353
+ "choose between",
354
+ "alternative",
355
+ "review",
356
+ "pros and cons",
357
+ "best",
358
+ "top",
359
+ "recommend"
360
+ ],
361
+ ready_to_buy: [
362
+ "buy now",
363
+ "purchase",
364
+ "get quote",
365
+ "sign up",
366
+ "subscribe",
367
+ "order now",
368
+ "book now",
369
+ "reserve",
370
+ "apply now",
371
+ "start now",
372
+ "pricing",
373
+ "cost",
374
+ "how much",
375
+ "discount",
376
+ "deal",
377
+ "promo code",
378
+ "coupon",
379
+ "special offer",
380
+ "ready to buy",
381
+ "want to buy",
382
+ "where can i buy",
383
+ "how to purchase"
384
+ ]
385
+ };
386
+ var INTEREST_PATTERNS = {
387
+ travel: ["travel", "trip", "vacation", "flight", "hotel", "destination", "tour", "cruise"],
388
+ fitness: ["fitness", "workout", "gym", "exercise", "health", "diet", "nutrition", "yoga"],
389
+ technology: ["tech", "software", "app", "computer", "phone", "gadget", "device", "AI"],
390
+ finance: ["finance", "money", "invest", "savings", "loan", "credit", "mortgage", "budget"],
391
+ insurance: ["insurance", "coverage", "policy", "claim", "premium", "deductible"],
392
+ automotive: ["car", "auto", "vehicle", "drive", "truck", "SUV", "motorcycle"],
393
+ education: ["learn", "course", "class", "school", "university", "degree", "certification"],
394
+ shopping: ["shop", "store", "buy", "sale", "discount", "deal", "online shopping"],
395
+ food: ["food", "restaurant", "cooking", "recipe", "meal", "dining", "cuisine"],
396
+ entertainment: ["movie", "show", "music", "game", "concert", "event", "streaming"],
397
+ home: ["home", "house", "apartment", "furniture", "decor", "renovation", "real estate"],
398
+ business: ["business", "company", "startup", "entrepreneur", "marketing", "sales"],
399
+ legal: ["legal", "lawyer", "attorney", "law", "contract", "lawsuit", "court"],
400
+ healthcare: ["health", "medical", "doctor", "hospital", "treatment", "therapy", "medicine"],
401
+ parenting: ["baby", "child", "parent", "family", "kids", "pregnancy", "school"],
402
+ wedding: ["wedding", "marriage", "engagement", "bride", "groom", "ceremony"],
403
+ pets: ["pet", "dog", "cat", "animal", "vet", "puppy", "kitten"],
404
+ beauty: ["beauty", "makeup", "skincare", "hair", "cosmetics", "salon", "spa"],
405
+ sports: ["sports", "game", "team", "player", "football", "basketball", "soccer"],
406
+ fashion: ["fashion", "clothing", "style", "outfit", "designer", "shoes", "accessories"]
407
+ };
408
+ function detectIntentStage(message, conversationHistory) {
409
+ const lowerMessage = message.toLowerCase();
410
+ const fullContext = conversationHistory ? [...conversationHistory, message].join(" ").toLowerCase() : lowerMessage;
411
+ for (const pattern of INTENT_PATTERNS.ready_to_buy) {
412
+ if (fullContext.includes(pattern)) {
413
+ return "ready_to_buy";
414
+ }
415
+ }
416
+ for (const pattern of INTENT_PATTERNS.comparison) {
417
+ if (fullContext.includes(pattern)) {
418
+ return "comparison";
419
+ }
420
+ }
421
+ for (const pattern of INTENT_PATTERNS.research) {
422
+ if (lowerMessage.includes(pattern)) {
423
+ return "research";
424
+ }
425
+ }
426
+ return void 0;
427
+ }
428
+ function extractInterests(message, conversationHistory) {
429
+ const interests = /* @__PURE__ */ new Set();
430
+ const validHistory = (conversationHistory || []).filter((msg) => typeof msg === "string" && msg.trim().length > 0);
431
+ const fullContext = validHistory.length > 0 ? [...validHistory, message].join(" ").toLowerCase() : message.toLowerCase();
432
+ for (const [interest, keywords] of Object.entries(INTEREST_PATTERNS)) {
433
+ for (const keyword of keywords) {
434
+ if (fullContext.includes(keyword)) {
435
+ interests.add(interest);
436
+ break;
437
+ }
438
+ }
439
+ }
440
+ return Array.from(interests);
441
+ }
442
+ function extractTopics(conversationHistory) {
443
+ if (!conversationHistory || conversationHistory.length === 0) {
444
+ return [];
445
+ }
446
+ const topics = [];
447
+ const seen = /* @__PURE__ */ new Set();
448
+ for (const message of conversationHistory.slice(-5)) {
449
+ const lowerMessage = message.toLowerCase();
450
+ for (const [topic, keywords] of Object.entries(INTEREST_PATTERNS)) {
451
+ if (!seen.has(topic)) {
452
+ for (const keyword of keywords) {
453
+ if (lowerMessage.includes(keyword)) {
454
+ topics.push(topic);
455
+ seen.add(topic);
456
+ break;
457
+ }
458
+ }
459
+ }
460
+ }
461
+ }
462
+ return topics.slice(0, 3);
463
+ }
464
+ function generateSessionId() {
465
+ const timestamp = Date.now().toString(36);
466
+ const random = Math.random().toString(36).substring(2, 9);
467
+ return `sess_${timestamp}_${random}`;
468
+ }
469
+ function detectPurchaseIntent(message, intentStage) {
470
+ if (intentStage === "ready_to_buy") {
471
+ return true;
472
+ }
473
+ const lowerMessage = message.toLowerCase();
474
+ const purchaseKeywords = [
475
+ "buy",
476
+ "purchase",
477
+ "order",
478
+ "get",
479
+ "subscribe",
480
+ "sign up",
481
+ "apply",
482
+ "book",
483
+ "reserve",
484
+ "quote",
485
+ "pricing",
486
+ "cost",
487
+ "how much",
488
+ "where can i"
489
+ ];
490
+ return purchaseKeywords.some((keyword) => lowerMessage.includes(keyword));
491
+ }
492
+ function calculateMessageCount(conversationHistory) {
493
+ return (conversationHistory?.length || 0) + 1;
494
+ }
495
+
356
496
  // src/client.ts
357
497
  var DEFAULT_BASE_URL = "https://peruwnbrqkvmrldhpoom.supabase.co/functions/v1";
358
498
  var DEFAULT_TIMEOUT_MS = 4e3;
@@ -498,6 +638,16 @@ var AttentionMarketClient = class {
498
638
  const limitedHistory = history.slice(-historyLimit);
499
639
  const contextParts = [...limitedHistory, params.userMessage];
500
640
  const context = contextParts.join("\n");
641
+ const intentStage = params.session_context?.intent_stage || detectIntentStage(params.userMessage, limitedHistory);
642
+ let interests = params.user_context?.interests || extractInterests(params.userMessage, limitedHistory);
643
+ interests = interests.filter((interest) => typeof interest === "string" && interest.trim().length > 0).map((interest) => interest.trim().toLowerCase()).slice(0, 10);
644
+ let recentTopics = params.user_context?.recent_topics || extractTopics(limitedHistory);
645
+ recentTopics = recentTopics.filter((topic) => typeof topic === "string" && topic.trim().length > 0).map((topic) => topic.trim().toLowerCase()).slice(0, 5);
646
+ const purchaseIntent = params.user_context?.purchase_intent !== void 0 ? Boolean(params.user_context.purchase_intent) : detectPurchaseIntent(params.userMessage, intentStage);
647
+ const rawSessionId = params.session_context?.session_id;
648
+ const sessionId = typeof rawSessionId === "string" && rawSessionId.trim().length > 0 ? rawSessionId.trim().slice(0, 100) : generateSessionId();
649
+ const rawMessageCount = params.session_context?.message_count;
650
+ const messageCount = typeof rawMessageCount === "number" && rawMessageCount >= 0 ? Math.min(rawMessageCount, 1e3) : calculateMessageCount(limitedHistory);
501
651
  const country = params.country || "US";
502
652
  const language = params.language || "en";
503
653
  const platform = params.platform || "web";
@@ -586,6 +736,23 @@ var AttentionMarketClient = class {
586
736
  user_intent: params.userMessage,
587
737
  // Use minimal response format by default for better performance
588
738
  response_format: "minimal",
739
+ // === Smart Context Fields (v0.15.0) ===
740
+ // Include user context if we have any data
741
+ ...(interests.length > 0 || recentTopics.length > 0 || purchaseIntent) && {
742
+ user_context: {
743
+ ...interests.length > 0 && { interests },
744
+ ...recentTopics.length > 0 && { recent_topics: recentTopics },
745
+ ...purchaseIntent && { purchase_intent: purchaseIntent }
746
+ }
747
+ },
748
+ // Include session context
749
+ ...sessionId && {
750
+ session_context: {
751
+ session_id: sessionId,
752
+ message_count: messageCount,
753
+ ...intentStage && { intent_stage: intentStage }
754
+ }
755
+ },
589
756
  // Developer controls (Phase 1: Quality & Brand Safety)
590
757
  ...params.minQualityScore !== void 0 && { minQualityScore: params.minQualityScore },
591
758
  ...params.allowedCategories && { allowedCategories: params.allowedCategories },
@@ -704,52 +871,6 @@ var AttentionMarketClient = class {
704
871
  const event = createImpressionEvent(params);
705
872
  return await this.track(event);
706
873
  }
707
- /**
708
- * Convenience method to track a click event.
709
- * Creates a click event using createClickEvent() and calls track().
710
- */
711
- async trackClick(params) {
712
- const event = createClickEvent(params);
713
- return await this.track(event);
714
- }
715
- /**
716
- * Ultra-simple method to track a click from an ad returned by decideFromContext().
717
- * Automatically extracts all required fields from the ad object.
718
- *
719
- * @param ad - The ad object returned by decideFromContext()
720
- * @param options - Just click_context (what you showed the user)
721
- *
722
- * @example
723
- * ```typescript
724
- * const ad = await client.decideFromContext({ userMessage: "I need car insurance" });
725
- * if (ad) {
726
- * await client.trackClickFromAd(ad, {
727
- * click_context: "Progressive: Get 20% off - Compare quotes"
728
- * });
729
- * }
730
- * ```
731
- */
732
- async trackClickFromAd(ad, options) {
733
- if (!this.agentId) {
734
- throw new Error("agentId is required for trackClickFromAd(). Set it in the constructor.");
735
- }
736
- const trackParams = {
737
- agent_id: this.agentId,
738
- request_id: ad.request_id,
739
- decision_id: ad.decision_id,
740
- unit_id: ad._ad.unit_id,
741
- tracking_token: ad.tracking_token,
742
- href: ad.click_url,
743
- click_context: options.click_context
744
- };
745
- if (options.metadata) {
746
- trackParams.metadata = options.metadata;
747
- }
748
- if (options.occurred_at) {
749
- trackParams.occurred_at = options.occurred_at;
750
- }
751
- return await this.trackClick(trackParams);
752
- }
753
874
  /**
754
875
  * Send feedback on an ad's performance to earn conversion-validated bonuses.
755
876
  *
@@ -1864,7 +1985,6 @@ function suggestTaxonomies(query) {
1864
1985
  NetworkError,
1865
1986
  TimeoutError,
1866
1987
  buildTaxonomy,
1867
- createClickEvent,
1868
1988
  createImpressionEvent,
1869
1989
  createOpportunity,
1870
1990
  detectIntent,