@the_ro_show/agent-ads-sdk 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AttentionMarket
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,376 @@
1
+ # AttentionMarket Agent Ads SDK
2
+
3
+ TypeScript SDK for integrating agent-native sponsored units (Sponsored Suggestions and Sponsored Tools) into AI agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @the_ro_show/agent-ads-sdk
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Store your credentials in environment variables:
14
+
15
+ ```bash
16
+ export ATTENTIONMARKET_API_KEY=am_live_...
17
+ export ATTENTIONMARKET_AGENT_ID=agt_01HV...
18
+ ```
19
+
20
+ **⚠️ Never commit API keys to version control.** See [SECURITY.md](./SECURITY.md) for best practices.
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import { AttentionMarketClient, createOpportunity, generateUUID } from '@the_ro_show/agent-ads-sdk';
26
+
27
+ const client = new AttentionMarketClient({ apiKey: process.env.ATTENTIONMARKET_API_KEY });
28
+
29
+ const opportunity = createOpportunity({
30
+ taxonomy: 'local_services.movers.quote',
31
+ country: 'US',
32
+ language: 'en',
33
+ platform: 'web',
34
+ query: 'Find movers in Brooklyn',
35
+ });
36
+
37
+ const unit = await client.decide({
38
+ request_id: generateUUID(),
39
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
40
+ placement: { type: 'sponsored_suggestion', surface: 'chat_response' },
41
+ opportunity,
42
+ });
43
+
44
+ if (unit && unit.unit_type === 'sponsored_suggestion') {
45
+ console.log(`[${unit.disclosure.label}] ${unit.disclosure.sponsor_name}`);
46
+ console.log(unit.suggestion.title);
47
+
48
+ await client.trackImpression({
49
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
50
+ request_id: 'req_id',
51
+ decision_id: 'decision_id',
52
+ unit_id: unit.unit_id,
53
+ tracking_token: unit.tracking.token,
54
+ });
55
+ }
56
+ ```
57
+
58
+ ## Agent Integration Examples
59
+
60
+ ### Minimal Examples (< 80 lines)
61
+
62
+ Start here for a quick overview:
63
+
64
+ - **[Claude](./examples/claude-tool-use-minimal.ts)** - Minimal tool use integration
65
+ - **[OpenAI GPT](./examples/openai-function-calling-minimal.ts)** - Minimal function calling
66
+ - **[Google Gemini](./examples/gemini-function-calling-minimal.ts)** - Minimal function declarations
67
+
68
+ Each shows: `createOpportunity` → `decide` → render → track
69
+
70
+ ### Full Examples (with detailed integration notes)
71
+
72
+ For production integrations:
73
+
74
+ - **[Claude (Anthropic)](./examples/claude-tool-use-full.ts)** - Complete tool use pattern with schemas and tracking
75
+ - **[OpenAI GPT](./examples/openai-function-calling-full.ts)** - Complete function calling with integration checklist
76
+ - **[Google Gemini](./examples/gemini-function-calling-full.ts)** - Complete function declarations with testing guide
77
+
78
+ Run any example with:
79
+ ```bash
80
+ npx tsx examples/claude-tool-use-minimal.ts
81
+ ```
82
+
83
+ ## Full Example with Raw Response
84
+
85
+ ```typescript
86
+ import {
87
+ AttentionMarketClient,
88
+ createOpportunity,
89
+ generateUUID,
90
+ } from '@the_ro_show/agent-ads-sdk';
91
+
92
+ const client = new AttentionMarketClient({
93
+ apiKey: process.env.ATTENTIONMARKET_API_KEY,
94
+ });
95
+
96
+ // Build opportunity
97
+ const opportunity = createOpportunity({
98
+ taxonomy: 'local_services.movers.quote',
99
+ country: 'US',
100
+ language: 'en',
101
+ platform: 'web',
102
+ query: 'Find movers in Brooklyn',
103
+ });
104
+
105
+ // Get full response (includes status, ttl_ms, all units)
106
+ const response = await client.decideRaw({
107
+ request_id: generateUUID(),
108
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
109
+ placement: {
110
+ type: 'sponsored_suggestion',
111
+ surface: 'chat_response',
112
+ },
113
+ opportunity,
114
+ });
115
+
116
+ if (response.status === 'filled') {
117
+ // Access all units and metadata
118
+ console.log(`TTL: ${response.ttl_ms}ms`);
119
+ console.log(`Units: ${response.units.length}`);
120
+
121
+ const unit = response.units[0];
122
+
123
+ // Render unit
124
+ if (unit && unit.unit_type === 'sponsored_suggestion') {
125
+ console.log(unit.suggestion.title);
126
+ }
127
+
128
+ // Track impression after rendering
129
+ await client.trackImpression({
130
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
131
+ request_id: response.request_id,
132
+ decision_id: response.decision_id,
133
+ unit_id: unit.unit_id,
134
+ tracking_token: unit.tracking.token,
135
+ metadata: { surface: 'chat_response' },
136
+ });
137
+
138
+ // Track click when user clicks
139
+ await client.trackClick({
140
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
141
+ request_id: response.request_id,
142
+ decision_id: response.decision_id,
143
+ unit_id: unit.unit_id,
144
+ tracking_token: unit.tracking.token,
145
+ href: unit.suggestion.action_url,
146
+ });
147
+ }
148
+ ```
149
+
150
+ ## API Methods
151
+
152
+ ### `decide(request, options?): Promise<AdUnit | null>`
153
+
154
+ Convenience method that returns the first ad unit or `null` if no fill.
155
+
156
+ ```typescript
157
+ const unit = await client.decide({
158
+ request_id: generateUUID(),
159
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
160
+ placement: {
161
+ type: 'sponsored_suggestion',
162
+ surface: 'chat_response',
163
+ },
164
+ opportunity,
165
+ });
166
+ ```
167
+
168
+ ### `decideRaw(request, options?): Promise<DecideResponse>`
169
+
170
+ Returns the full response including status, ttl_ms, and all units.
171
+
172
+ ```typescript
173
+ const response = await client.decideRaw({
174
+ request_id: generateUUID(),
175
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
176
+ placement: { type: 'sponsored_suggestion', surface: 'chat_response' },
177
+ opportunity,
178
+ }, {
179
+ idempotencyKey: 'optional-idempotency-key',
180
+ });
181
+ ```
182
+
183
+ ### `trackImpression(params): Promise<EventIngestResponse>`
184
+
185
+ Convenience method to track when a unit is rendered.
186
+
187
+ ```typescript
188
+ await client.trackImpression({
189
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
190
+ request_id: 'req_123',
191
+ decision_id: 'dec_456',
192
+ unit_id: 'unit_789',
193
+ tracking_token: 'trk_abc',
194
+ metadata: { surface: 'chat_response' },
195
+ });
196
+ ```
197
+
198
+ ### `trackClick(params): Promise<EventIngestResponse>`
199
+
200
+ Convenience method to track when a user clicks a unit.
201
+
202
+ ```typescript
203
+ await client.trackClick({
204
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
205
+ request_id: 'req_123',
206
+ decision_id: 'dec_456',
207
+ unit_id: 'unit_789',
208
+ tracking_token: 'trk_abc',
209
+ href: 'https://example.com/action',
210
+ });
211
+ ```
212
+
213
+ ### `track(event): Promise<EventIngestResponse>`
214
+
215
+ Low-level method to track any event type.
216
+
217
+ ```typescript
218
+ await client.track({
219
+ event_id: generateUUID(),
220
+ occurred_at: new Date().toISOString(),
221
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
222
+ request_id: 'req_123',
223
+ decision_id: 'dec_456',
224
+ unit_id: 'unit_789',
225
+ event_type: 'impression',
226
+ tracking_token: 'trk_abc',
227
+ });
228
+ ```
229
+
230
+ ### `getPolicy(): Promise<PolicyResponse>`
231
+
232
+ Fetch policy constraints and formatting requirements.
233
+
234
+ ```typescript
235
+ const policy = await client.getPolicy();
236
+ console.log(policy.defaults.max_units_per_response);
237
+ console.log(policy.disclosure.label);
238
+ ```
239
+
240
+ ### `signupAgent(request, options?): Promise<AgentSignupResponse>` (static)
241
+
242
+ Register a new agent (unauthenticated endpoint).
243
+
244
+ ```typescript
245
+ const signup = await AttentionMarketClient.signupAgent({
246
+ owner_email: 'owner@company.com',
247
+ agent_name: 'My Agent',
248
+ sdk: 'typescript',
249
+ environment: 'test',
250
+ });
251
+
252
+ console.log(signup.agent_id);
253
+ console.log(signup.api_key);
254
+ ```
255
+
256
+ ## Helper Functions
257
+
258
+ ### `createOpportunity(params): Opportunity`
259
+
260
+ Build a valid Opportunity object with safe defaults.
261
+
262
+ ```typescript
263
+ const opportunity = createOpportunity({
264
+ // Required
265
+ taxonomy: 'local_services.movers.quote',
266
+ country: 'US',
267
+ language: 'en',
268
+ platform: 'web',
269
+
270
+ // Optional
271
+ query: 'Find movers in Brooklyn',
272
+ region: 'NY',
273
+ city: 'New York',
274
+
275
+ // Optional overrides (with defaults shown)
276
+ constraints: {
277
+ max_units: 1,
278
+ allowed_unit_types: ['sponsored_suggestion'],
279
+ blocked_categories: ['adult'],
280
+ },
281
+ privacy: {
282
+ data_policy: 'coarse_only',
283
+ },
284
+ });
285
+ ```
286
+
287
+ ### `createImpressionEvent(params): EventIngestRequest`
288
+
289
+ Build an impression event payload.
290
+
291
+ ```typescript
292
+ import { createImpressionEvent } from '@the_ro_show/agent-ads-sdk';
293
+
294
+ const event = createImpressionEvent({
295
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
296
+ request_id: 'req_123',
297
+ decision_id: 'dec_456',
298
+ unit_id: 'unit_789',
299
+ tracking_token: 'trk_abc',
300
+ occurred_at: new Date().toISOString(), // optional, auto-generated
301
+ metadata: { surface: 'chat_response' }, // optional
302
+ });
303
+
304
+ await client.track(event);
305
+ ```
306
+
307
+ ### `createClickEvent(params): EventIngestRequest`
308
+
309
+ Build a click event payload.
310
+
311
+ ```typescript
312
+ import { createClickEvent } from '@the_ro_show/agent-ads-sdk';
313
+
314
+ const event = createClickEvent({
315
+ agent_id: process.env.ATTENTIONMARKET_AGENT_ID,
316
+ request_id: 'req_123',
317
+ decision_id: 'dec_456',
318
+ unit_id: 'unit_789',
319
+ tracking_token: 'trk_abc',
320
+ href: 'https://example.com',
321
+ occurred_at: new Date().toISOString(), // optional, auto-generated
322
+ });
323
+
324
+ await client.track(event);
325
+ ```
326
+
327
+ ### `generateUUID(): string`
328
+
329
+ Generate a UUID v4 for request_id, event_id, etc.
330
+
331
+ ```typescript
332
+ import { generateUUID } from '@the_ro_show/agent-ads-sdk';
333
+
334
+ const requestId = generateUUID();
335
+ ```
336
+
337
+ ## Features
338
+
339
+ - ✅ TypeScript support with full type definitions
340
+ - ✅ Automatic retries with exponential backoff
341
+ - ✅ Configurable timeouts (default 4000ms)
342
+ - ✅ Idempotency support
343
+ - ✅ Discriminated union types for type-safe ad units
344
+ - ✅ Helper functions for common operations
345
+ - ✅ No external runtime dependencies (Node.js 18+)
346
+
347
+ ## Requirements
348
+
349
+ - Node.js 18 or higher
350
+ - TypeScript 5.3 or higher (for development)
351
+
352
+ ## Error Handling
353
+
354
+ The SDK throws typed errors that include full API context:
355
+
356
+ ```typescript
357
+ import { APIRequestError, NetworkError, TimeoutError } from '@the_ro_show/agent-ads-sdk';
358
+
359
+ try {
360
+ const unit = await client.decide(request);
361
+ } catch (error) {
362
+ if (error instanceof APIRequestError) {
363
+ console.error(`API Error [${error.statusCode}]: ${error.errorCode}`);
364
+ console.error(`Message: ${error.message}`);
365
+ console.error(`Request ID: ${error.requestId}`);
366
+ } else if (error instanceof TimeoutError) {
367
+ console.error('Request timed out');
368
+ } else if (error instanceof NetworkError) {
369
+ console.error('Network error:', error.message);
370
+ }
371
+ }
372
+ ```
373
+
374
+ ## License
375
+
376
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,50 @@
1
+ # Security Policy
2
+
3
+ ## API Key Management
4
+
5
+ **IMPORTANT**: Never commit API keys to version control.
6
+
7
+ Your AttentionMarket API key (`am_live_...` or `am_test_...`) provides access to your agent's account and billing. Follow these best practices:
8
+
9
+ ### Environment Variables
10
+
11
+ Store your API key in environment variables, not in code:
12
+
13
+ ```bash
14
+ export ATTENTIONMARKET_API_KEY=am_live_...
15
+ ```
16
+
17
+ Then use it in your application:
18
+
19
+ ```typescript
20
+ const client = new AttentionMarketClient({
21
+ apiKey: process.env.ATTENTIONMARKET_API_KEY,
22
+ });
23
+ ```
24
+
25
+ ### .gitignore
26
+
27
+ Ensure your `.gitignore` includes:
28
+
29
+ ```
30
+ .env
31
+ .env.local
32
+ .env.*.local
33
+ ```
34
+
35
+ ### Production Deployments
36
+
37
+ - Use secure secret management systems (AWS Secrets Manager, GitHub Secrets, etc.)
38
+ - Rotate API keys periodically
39
+ - Use `am_test_...` keys for development and testing
40
+ - Use `am_live_...` keys only in production environments
41
+
42
+ ## Reporting Security Issues
43
+
44
+ If you discover a security vulnerability in this SDK, please email security@attentionmarket.com with:
45
+
46
+ - Description of the vulnerability
47
+ - Steps to reproduce
48
+ - Potential impact
49
+
50
+ Do not open public GitHub issues for security vulnerabilities.