@the_ro_show/agent-ads-sdk 0.13.3 → 0.14.2
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 +91 -0
- package/dist/index.d.mts +26 -5
- package/dist/index.d.ts +26 -5
- package/dist/index.js +54 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -368,6 +368,65 @@ const ad = await client.decideFromContext({
|
|
|
368
368
|
});
|
|
369
369
|
```
|
|
370
370
|
|
|
371
|
+
## Performance Optimization
|
|
372
|
+
|
|
373
|
+
### Payload Optimization (v0.14.0+)
|
|
374
|
+
|
|
375
|
+
The SDK automatically uses an optimized minimal payload format that reduces response size by **84%** (from 3.2KB to ~520B) while maintaining all essential functionality including relevance scores. This improves:
|
|
376
|
+
|
|
377
|
+
- **Network efficiency:** 6x less data transfer
|
|
378
|
+
- **Response speed:** Faster parsing and processing
|
|
379
|
+
- **Mobile performance:** Lower bandwidth usage
|
|
380
|
+
- **Cost savings:** Reduced data transfer costs
|
|
381
|
+
|
|
382
|
+
#### Response Formats
|
|
383
|
+
|
|
384
|
+
The SDK supports three response formats:
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// Minimal format (default, ~520B) - Essentials + relevance
|
|
388
|
+
const ad = await client.decideFromContext({
|
|
389
|
+
userMessage: "I need car insurance",
|
|
390
|
+
response_format: 'minimal' // Optional, this is the default
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// Returns:
|
|
394
|
+
{
|
|
395
|
+
creative: { title, body, cta },
|
|
396
|
+
click_url: string,
|
|
397
|
+
tracking_token: string,
|
|
398
|
+
advertiser_id: string,
|
|
399
|
+
payout: number,
|
|
400
|
+
relevance_score: number // 0.0-1.0 for frontend filtering
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
For advanced use cases, you can request more detailed responses:
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Standard format (645B) - Includes disclosure info
|
|
408
|
+
const ad = await client.decide({
|
|
409
|
+
response_format: 'standard',
|
|
410
|
+
// ... other params
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Verbose format (3.1KB) - Full response with all metadata
|
|
414
|
+
const ad = await client.decide({
|
|
415
|
+
response_format: 'verbose',
|
|
416
|
+
// ... other params
|
|
417
|
+
});
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### Format Comparison
|
|
421
|
+
|
|
422
|
+
| Format | Size | Use Case | Auto-impression |
|
|
423
|
+
|--------|------|----------|-----------------|
|
|
424
|
+
| **minimal** | ~520B | Production apps (default, includes relevance) | ✅ Yes |
|
|
425
|
+
| **standard** | ~645B | Apps needing disclosure details | ❌ Manual |
|
|
426
|
+
| **verbose** | ~3.1KB | Debugging, analytics | ❌ Manual |
|
|
427
|
+
|
|
428
|
+
**Note:** The minimal format automatically tracks impressions for you. When using standard or verbose formats with the raw `decide()` API, you must manually track impressions.
|
|
429
|
+
|
|
371
430
|
## Advanced Features
|
|
372
431
|
|
|
373
432
|
### Multi-Turn Conversations
|
|
@@ -497,6 +556,38 @@ Use test API keys (`am_test_...`) for development and testing. Test keys:
|
|
|
497
556
|
|
|
498
557
|
Switch to live keys (`am_live_...`) when deploying to production.
|
|
499
558
|
|
|
559
|
+
## 🤖 Claude Code Integration
|
|
560
|
+
|
|
561
|
+
Building with Claude Code? We've created ready-to-use prompts for seamless integration.
|
|
562
|
+
|
|
563
|
+
### Quick Start (One Line)
|
|
564
|
+
|
|
565
|
+
```
|
|
566
|
+
I want to add AttentionMarket ads to my AI app. Credentials:
|
|
567
|
+
- API Key: am_test_YOUR_KEY
|
|
568
|
+
- Agent ID: agt_YOUR_ID
|
|
569
|
+
Create a simple getRelevantAd(message) function that returns ads only when relevant (score>0.7).
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Full Integration Guide
|
|
573
|
+
|
|
574
|
+
📖 **[Claude Code Integration Guide](CLAUDE_CODE_INTEGRATION.md)** — Copy-paste prompts for:
|
|
575
|
+
- Natural conversation integration
|
|
576
|
+
- Advanced filtering & brand safety
|
|
577
|
+
- Testing & analytics setup
|
|
578
|
+
- Mobile app integration
|
|
579
|
+
- Common patterns & best practices
|
|
580
|
+
|
|
581
|
+
### Performance Metrics
|
|
582
|
+
|
|
583
|
+
| Metric | Expected Performance |
|
|
584
|
+
|--------|---------------------|
|
|
585
|
+
| **CTR** | 5-12% average |
|
|
586
|
+
| **Revenue/Click** | $0.50 - $15.00 |
|
|
587
|
+
| **Fill Rate** | 40-60% |
|
|
588
|
+
| **API Latency** | < 100ms p95 |
|
|
589
|
+
| **Payload Size** | ~520 bytes |
|
|
590
|
+
|
|
500
591
|
## Support
|
|
501
592
|
|
|
502
593
|
- **Documentation:** [docs.attentionmarket.ai](https://docs.attentionmarket.ai)
|
package/dist/index.d.mts
CHANGED
|
@@ -25,6 +25,9 @@ interface DecideRequest {
|
|
|
25
25
|
context?: string;
|
|
26
26
|
/** Detected or inferred user intent for semantic matching (optional) */
|
|
27
27
|
user_intent?: string;
|
|
28
|
+
/** Response format: 'minimal' | 'standard' | 'verbose' (default: 'minimal') */
|
|
29
|
+
response_format?: string;
|
|
30
|
+
[key: string]: any;
|
|
28
31
|
}
|
|
29
32
|
/**
|
|
30
33
|
* Simplified request for semantic context-based ad matching.
|
|
@@ -127,11 +130,27 @@ interface DecideFromContextRequest {
|
|
|
127
130
|
optimizeFor?: 'revenue' | 'relevance';
|
|
128
131
|
}
|
|
129
132
|
interface DecideResponse {
|
|
130
|
-
request_id
|
|
131
|
-
decision_id
|
|
132
|
-
status
|
|
133
|
-
ttl_ms
|
|
134
|
-
units
|
|
133
|
+
request_id?: string;
|
|
134
|
+
decision_id?: string;
|
|
135
|
+
status?: 'filled' | 'no_fill';
|
|
136
|
+
ttl_ms?: number;
|
|
137
|
+
units?: AdUnit[];
|
|
138
|
+
creative?: {
|
|
139
|
+
title: string;
|
|
140
|
+
body: string;
|
|
141
|
+
cta: string;
|
|
142
|
+
};
|
|
143
|
+
click_url?: string;
|
|
144
|
+
tracking_token?: string;
|
|
145
|
+
advertiser_id?: string;
|
|
146
|
+
payout?: number;
|
|
147
|
+
disclosure?: {
|
|
148
|
+
label: string;
|
|
149
|
+
explanation: string;
|
|
150
|
+
sponsor_name: string;
|
|
151
|
+
};
|
|
152
|
+
relevance_score?: number;
|
|
153
|
+
[key: string]: any;
|
|
135
154
|
}
|
|
136
155
|
type PlacementType = 'sponsored_suggestion' | 'sponsored_block' | 'sponsored_tool';
|
|
137
156
|
interface Placement {
|
|
@@ -531,6 +550,8 @@ interface AdResponse {
|
|
|
531
550
|
tracking_url?: string;
|
|
532
551
|
/** Tracking token for event tracking */
|
|
533
552
|
tracking_token: string;
|
|
553
|
+
/** Relevance score (0.0-1.0) for frontend rendering decisions */
|
|
554
|
+
relevance_score?: number;
|
|
534
555
|
/** Disclosure information */
|
|
535
556
|
disclosure: Disclosure;
|
|
536
557
|
/** Full ad unit (for advanced usage) */
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ interface DecideRequest {
|
|
|
25
25
|
context?: string;
|
|
26
26
|
/** Detected or inferred user intent for semantic matching (optional) */
|
|
27
27
|
user_intent?: string;
|
|
28
|
+
/** Response format: 'minimal' | 'standard' | 'verbose' (default: 'minimal') */
|
|
29
|
+
response_format?: string;
|
|
30
|
+
[key: string]: any;
|
|
28
31
|
}
|
|
29
32
|
/**
|
|
30
33
|
* Simplified request for semantic context-based ad matching.
|
|
@@ -127,11 +130,27 @@ interface DecideFromContextRequest {
|
|
|
127
130
|
optimizeFor?: 'revenue' | 'relevance';
|
|
128
131
|
}
|
|
129
132
|
interface DecideResponse {
|
|
130
|
-
request_id
|
|
131
|
-
decision_id
|
|
132
|
-
status
|
|
133
|
-
ttl_ms
|
|
134
|
-
units
|
|
133
|
+
request_id?: string;
|
|
134
|
+
decision_id?: string;
|
|
135
|
+
status?: 'filled' | 'no_fill';
|
|
136
|
+
ttl_ms?: number;
|
|
137
|
+
units?: AdUnit[];
|
|
138
|
+
creative?: {
|
|
139
|
+
title: string;
|
|
140
|
+
body: string;
|
|
141
|
+
cta: string;
|
|
142
|
+
};
|
|
143
|
+
click_url?: string;
|
|
144
|
+
tracking_token?: string;
|
|
145
|
+
advertiser_id?: string;
|
|
146
|
+
payout?: number;
|
|
147
|
+
disclosure?: {
|
|
148
|
+
label: string;
|
|
149
|
+
explanation: string;
|
|
150
|
+
sponsor_name: string;
|
|
151
|
+
};
|
|
152
|
+
relevance_score?: number;
|
|
153
|
+
[key: string]: any;
|
|
135
154
|
}
|
|
136
155
|
type PlacementType = 'sponsored_suggestion' | 'sponsored_block' | 'sponsored_tool';
|
|
137
156
|
interface Placement {
|
|
@@ -531,6 +550,8 @@ interface AdResponse {
|
|
|
531
550
|
tracking_url?: string;
|
|
532
551
|
/** Tracking token for event tracking */
|
|
533
552
|
tracking_token: string;
|
|
553
|
+
/** Relevance score (0.0-1.0) for frontend rendering decisions */
|
|
554
|
+
relevance_score?: number;
|
|
534
555
|
/** Disclosure information */
|
|
535
556
|
disclosure: Disclosure;
|
|
536
557
|
/** Full ad unit (for advanced usage) */
|
package/dist/index.js
CHANGED
|
@@ -468,7 +468,7 @@ var AttentionMarketClient = class {
|
|
|
468
468
|
if (response.status === "no_fill") {
|
|
469
469
|
return null;
|
|
470
470
|
}
|
|
471
|
-
return response.units[0] ?? null;
|
|
471
|
+
return response.units?.[0] ?? null;
|
|
472
472
|
}
|
|
473
473
|
/**
|
|
474
474
|
* Simplified ad matching using conversation context and semantic search.
|
|
@@ -584,6 +584,8 @@ var AttentionMarketClient = class {
|
|
|
584
584
|
},
|
|
585
585
|
context,
|
|
586
586
|
user_intent: params.userMessage,
|
|
587
|
+
// Use minimal response format by default for better performance
|
|
588
|
+
response_format: "minimal",
|
|
587
589
|
// Developer controls (Phase 1: Quality & Brand Safety)
|
|
588
590
|
...params.minQualityScore !== void 0 && { minQualityScore: params.minQualityScore },
|
|
589
591
|
...params.allowedCategories && { allowedCategories: params.allowedCategories },
|
|
@@ -595,7 +597,49 @@ var AttentionMarketClient = class {
|
|
|
595
597
|
...params.optimizeFor && { optimizeFor: params.optimizeFor }
|
|
596
598
|
};
|
|
597
599
|
const response = await this.decideRaw(request, options);
|
|
598
|
-
if (response
|
|
600
|
+
if (response && response.creative) {
|
|
601
|
+
if (response["_meta"]) {
|
|
602
|
+
try {
|
|
603
|
+
await this.track({
|
|
604
|
+
event_id: `evt_${generateUUID()}`,
|
|
605
|
+
event_type: "impression",
|
|
606
|
+
occurred_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
607
|
+
agent_id: this.agentId,
|
|
608
|
+
request_id: response["_meta"]["request_id"],
|
|
609
|
+
decision_id: response["_meta"]["decision_id"],
|
|
610
|
+
unit_id: response["_meta"]["unit_id"],
|
|
611
|
+
tracking_token: response.tracking_token
|
|
612
|
+
});
|
|
613
|
+
} catch (error) {
|
|
614
|
+
console.warn("[AttentionMarket] Failed to auto-track impression:", error);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
const adResponse2 = {
|
|
618
|
+
request_id: request.request_id,
|
|
619
|
+
decision_id: `dec_${generateUUID()}`,
|
|
620
|
+
advertiser_id: response.advertiser_id || "",
|
|
621
|
+
ad_type: "link",
|
|
622
|
+
payout: response.payout || 0,
|
|
623
|
+
creative: response.creative,
|
|
624
|
+
click_url: response.click_url || "",
|
|
625
|
+
tracking_url: response.click_url || "",
|
|
626
|
+
// Same as click_url
|
|
627
|
+
tracking_token: response.tracking_token || "",
|
|
628
|
+
...response.relevance_score !== void 0 && { relevance_score: response.relevance_score },
|
|
629
|
+
disclosure: response.disclosure || {
|
|
630
|
+
label: "Sponsored",
|
|
631
|
+
explanation: "This is a paid advertisement",
|
|
632
|
+
sponsor_name: "Advertiser"
|
|
633
|
+
},
|
|
634
|
+
// Internal fields preserved for backward compatibility
|
|
635
|
+
_ad: {
|
|
636
|
+
unit_id: "",
|
|
637
|
+
tracking: { token: response.tracking_token || "" }
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
return adResponse2;
|
|
641
|
+
}
|
|
642
|
+
if (!response || response.status === "no_fill" || !response.units || response.units.length === 0) {
|
|
599
643
|
return null;
|
|
600
644
|
}
|
|
601
645
|
const adUnit = response.units[0];
|
|
@@ -908,7 +952,7 @@ var AttentionMarketClient = class {
|
|
|
908
952
|
user_intent: params.intentKey
|
|
909
953
|
};
|
|
910
954
|
const response = await this.decideRaw(request, { idempotencyKey });
|
|
911
|
-
if (response.status === "no_fill" || response.units.length === 0) {
|
|
955
|
+
if (response.status === "no_fill" || !response.units || response.units.length === 0) {
|
|
912
956
|
return null;
|
|
913
957
|
}
|
|
914
958
|
const adUnit = response.units[0];
|
|
@@ -919,7 +963,7 @@ var AttentionMarketClient = class {
|
|
|
919
963
|
const matchMethod = semanticContext ? "hybrid" : "semantic";
|
|
920
964
|
return {
|
|
921
965
|
offer_id: adUnit.unit_id,
|
|
922
|
-
request_id: response.request_id,
|
|
966
|
+
request_id: response.request_id || "",
|
|
923
967
|
impression_id: impressionId,
|
|
924
968
|
// LIMITATION: Backend doesn't return campaign_id yet - use unit_id as placeholder
|
|
925
969
|
campaign_id: adUnit.unit_id,
|
|
@@ -950,7 +994,7 @@ var AttentionMarketClient = class {
|
|
|
950
994
|
...params.revenueSharePct !== void 0 ? { source_agent_pct: params.revenueSharePct } : {}
|
|
951
995
|
}
|
|
952
996
|
} : {},
|
|
953
|
-
ttl_ms: response.ttl_ms
|
|
997
|
+
ttl_ms: response.ttl_ms || 3e5
|
|
954
998
|
};
|
|
955
999
|
}
|
|
956
1000
|
/**
|
|
@@ -1041,7 +1085,7 @@ var AttentionMarketClient = class {
|
|
|
1041
1085
|
user_intent: params.userMessage
|
|
1042
1086
|
};
|
|
1043
1087
|
const response = await this.decideRaw(request, { idempotencyKey });
|
|
1044
|
-
if (response.status === "no_fill" || response.units.length === 0) {
|
|
1088
|
+
if (response.status === "no_fill" || !response.units || response.units.length === 0) {
|
|
1045
1089
|
return null;
|
|
1046
1090
|
}
|
|
1047
1091
|
const adUnit = response.units[0];
|
|
@@ -1052,7 +1096,7 @@ var AttentionMarketClient = class {
|
|
|
1052
1096
|
const similarity = adUnit._score?.relevance;
|
|
1053
1097
|
return {
|
|
1054
1098
|
offer_id: adUnit.unit_id,
|
|
1055
|
-
request_id: response.request_id,
|
|
1099
|
+
request_id: response.request_id || "",
|
|
1056
1100
|
impression_id: impressionId,
|
|
1057
1101
|
// LIMITATION: Backend doesn't return campaign_id yet - use unit_id as placeholder
|
|
1058
1102
|
campaign_id: adUnit.unit_id,
|
|
@@ -1083,7 +1127,7 @@ var AttentionMarketClient = class {
|
|
|
1083
1127
|
...params.revenueSharePct !== void 0 ? { source_agent_pct: params.revenueSharePct } : {}
|
|
1084
1128
|
}
|
|
1085
1129
|
} : {},
|
|
1086
|
-
ttl_ms: response.ttl_ms
|
|
1130
|
+
ttl_ms: response.ttl_ms || 3e5
|
|
1087
1131
|
};
|
|
1088
1132
|
}
|
|
1089
1133
|
// ============================================================================
|
|
@@ -1169,7 +1213,7 @@ var AttentionMarketClient = class {
|
|
|
1169
1213
|
user_intent: params.taskDescription
|
|
1170
1214
|
};
|
|
1171
1215
|
const response = await this.decideRaw(request);
|
|
1172
|
-
if (response.status === "no_fill" || response.units.length === 0) {
|
|
1216
|
+
if (response.status === "no_fill" || !response.units || response.units.length === 0) {
|
|
1173
1217
|
return null;
|
|
1174
1218
|
}
|
|
1175
1219
|
const adUnit = response.units[0];
|
|
@@ -1430,7 +1474,7 @@ var MockAttentionMarketClient = class {
|
|
|
1430
1474
|
*/
|
|
1431
1475
|
async decide(request) {
|
|
1432
1476
|
const response = await this.decideRaw(request);
|
|
1433
|
-
if (response.status === "filled" && response.units.length > 0) {
|
|
1477
|
+
if (response.status === "filled" && response.units && response.units.length > 0) {
|
|
1434
1478
|
return response.units[0] || null;
|
|
1435
1479
|
}
|
|
1436
1480
|
return null;
|