@gravity-ai/api 1.1.3 → 1.1.5

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
@@ -1,207 +1,162 @@
1
+ import { G as GravityAdsOptions, I as IncomingAdRequest, M as MessageObject, P as PlacementObject, a as GravityAdsResult, b as GravityContextOverrides, c as GravityContext, A as AdParams, d as Ad } from './types-DYbti_CZ.mjs';
2
+ export { e as ApiErrorResponse, D as DeviceObject, g as Gender, f as Placement, R as Role, U as UserObject } from './types-DYbti_CZ.mjs';
3
+
1
4
  /**
2
- * Role type for conversation messages
3
- * @description Indicates whether a message is from the user or the AI assistant
4
- */
5
- type Role = 'user' | 'assistant';
6
- /**
7
- * Gender type for user targeting
8
- * @description Used for demographic targeting of advertisements
9
- */
10
- type Gender = 'male' | 'female' | 'other';
11
- /**
12
- * Placement positions for ad rendering
13
- * @description Specifies where ads should appear relative to the AI response
14
- */
15
- type Placement = 'above_response' | 'below_response' | 'inline_response' | 'left_response' | 'right_response';
16
- /**
17
- * Individual ad placement specification
18
- * @description Defines a single ad slot with its position and optional tracking ID
5
+ * Gravity ad client.
6
+ *
7
+ * Configure once at startup, then call `getAds()` in your endpoint handlers.
8
+ * Test ads are returned by default — pass `production: true` when you're ready
9
+ * to go live.
10
+ *
19
11
  * @example
20
- * ```typescript
21
- * const placement: PlacementObject = {
22
- * placement: 'below_response',
23
- * placement_id: 'sidebar-1'
24
- * };
12
+ * ```ts
13
+ * import { Gravity } from '@gravity-ai/api';
14
+ *
15
+ * const gravity = new Gravity({ production: true });
16
+ *
17
+ * app.post('/api/chat', async (req, res) => {
18
+ * const { messages } = req.body;
19
+ * const adPromise = gravity.getAds(req, messages, [
20
+ * { placement: 'below_response', placement_id: 'main' },
21
+ * ]);
22
+ *
23
+ * // stream your LLM response...
24
+ *
25
+ * const { ads } = await adPromise;
26
+ * res.write(`data: ${JSON.stringify({ type: 'done', ads })}\n\n`);
27
+ * res.end();
28
+ * });
25
29
  * ```
26
30
  */
27
- interface PlacementObject {
28
- /** Position where the ad should appear (required) */
29
- placement: Placement;
30
- /** Tracking ID for this specific ad slot (required) */
31
- placement_id: string;
31
+ declare class Gravity {
32
+ private opts;
33
+ /**
34
+ * @param opts - Configuration applied to every `getAds()` call.
35
+ *
36
+ * | Option | Type | Default | Description |
37
+ * |--------|------|---------|-------------|
38
+ * | `apiKey` | `string` | `process.env.GRAVITY_API_KEY` | Gravity API key |
39
+ * | `production` | `boolean` | `false` | `true` = real ads. `false` = test ads (no billing). |
40
+ * | `relevancy` | `number` | `0.2` | Minimum relevancy threshold (0-1) |
41
+ * | `timeoutMs` | `number` | `3000` | Request timeout in ms |
42
+ * | `excludedTopics` | `string[]` | — | Topics to exclude from ad matching |
43
+ * | `gravityApi` | `string` | production URL | Custom API endpoint |
44
+ */
45
+ constructor(opts?: GravityAdsOptions);
46
+ /**
47
+ * Fetch ads from the Gravity API. **Never throws.**
48
+ *
49
+ * Reads `gravity_context` from `req.body` (sent by the client via
50
+ * `gravityContext()`), extracts the end-user's IP from request headers,
51
+ * and calls the Gravity ad endpoint.
52
+ *
53
+ * @param req - Server request object (Express, Fastify, Next.js, etc.)
54
+ * @param messages - Conversation `[{ role, content }]` — last 2 turns sent
55
+ * @param placements - Ad slots, e.g. `[{ placement: "below_response", placement_id: "main" }]`
56
+ * @param overrides - Per-call overrides that merge on top of constructor config
57
+ * @returns `{ ads, status, elapsed, requestBody, error? }` — always resolves
58
+ */
59
+ getAds(req: IncomingAdRequest, messages: MessageObject[], placements: PlacementObject[], overrides?: GravityAdsOptions): Promise<GravityAdsResult>;
32
60
  }
61
+
33
62
  /**
34
- * Represents a single message in a conversation
35
- * @description Used to provide conversation context for contextual ad targeting
36
- * @example
37
- * ```typescript
38
- * const message: MessageObject = {
39
- * role: 'user',
40
- * content: 'I need help finding a new laptop.'
41
- * };
63
+ * Collect device + user context and return a plain object to include
64
+ * in your request body as `gravity_context`.
65
+ *
66
+ * Works in browsers, Node.js, Bun, and Deno. Auto-detects the runtime
67
+ * and collects the appropriate signals (user-agent, screen size, timezone, etc.).
68
+ *
69
+ * Nothing is written to disk, localStorage, or cookies.
70
+ *
71
+ * @param overrides - Must include `sessionId` and `user.userId`.
72
+ *
73
+ * @example Browser (React, Next.js, vanilla JS)
74
+ * ```ts
75
+ * import { gravityContext } from '@gravity-ai/api';
76
+ *
77
+ * const ctx = gravityContext({
78
+ * sessionId: chatSession.id,
79
+ * user: { userId: currentUser.id },
80
+ * });
81
+ *
82
+ * fetch('/api/chat', {
83
+ * method: 'POST',
84
+ * body: JSON.stringify({ messages, gravity_context: ctx }),
85
+ * });
42
86
  * ```
43
- */
44
- interface MessageObject {
45
- /** The role of the message sender - either 'user' or 'assistant' */
46
- role: Role;
47
- /** The text content of the message */
48
- content: string;
49
- }
50
- /**
51
- * Device and location information for ad targeting
52
- * @description Provides device-level context for better ad relevance and compliance
53
- * @example
54
- * ```typescript
55
- * const device: DeviceObject = {
56
- * ip: '192.168.1.1',
57
- * country: 'US',
58
- * ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...',
59
- * os: 'macOS'
60
- * };
87
+ *
88
+ * @example Node.js CLI
89
+ * ```ts
90
+ * const ctx = gravityContext({
91
+ * sessionId: conversationId,
92
+ * user: { userId: 'cli-user-1' },
93
+ * });
61
94
  * ```
62
95
  */
63
- interface DeviceObject {
64
- /** User's IP address for geo-targeting (required) */
65
- ip: string;
66
- /** Browser user-agent string (optional for non-web publishers like IDEs, CLIs, mobile apps) */
67
- ua?: string;
68
- /** ISO 3166-1 alpha-2 country code (e.g., 'US', 'GB', 'DE') */
69
- country?: string;
70
- /** Operating system name (e.g., 'macOS', 'Windows', 'iOS', 'Android') */
71
- os?: string;
72
- /** Identifier for Advertisers (mobile advertising ID) */
73
- ifa?: string;
74
- /** Additional device properties (timezone, locale, browser, device_type, screen dimensions, etc.) */
75
- [key: string]: string | number | boolean | undefined;
76
- }
96
+ declare function gravityContext(overrides: GravityContextOverrides): GravityContext;
97
+
77
98
  /**
78
- * User profile information for ad targeting
79
- * @description Demographic and interest data for personalized ad delivery
80
- * @example
81
- * ```typescript
82
- * const user: UserObject = {
83
- * uid: 'user-123',
84
- * gender: 'male',
85
- * age: '25-34',
86
- * keywords: 'technology,programming,gaming'
87
- * };
88
- * ```
99
+ * Trim conversation to the last N turns sent to Gravity for contextual matching.
89
100
  */
90
- interface UserObject {
91
- /** Unique user identifier for improving ad relevance */
92
- uid?: string;
93
- /** User's gender for demographic targeting */
94
- gender?: Gender;
95
- /** Age range string (e.g., '18-24', '25-34', '35-44', '45-54', '55-64', '65+') */
96
- age?: string;
97
- /** Comma-separated keywords representing user interests */
98
- keywords?: string;
99
- /** Additional user properties (email, subscription_tier, user_interests, company_size, etc.) */
100
- [key: string]: string | string[] | number | boolean | Gender | undefined;
101
- }
101
+ declare function toGravityMessages(messages: MessageObject[], maxTurns?: number): MessageObject[];
102
102
  /**
103
- * Parameters for requesting an advertisement
104
- * @description The complete request payload for the getAd() method
105
- * @example
106
- * ```typescript
107
- * const params: AdParams = {
108
- * messages: [
109
- * { role: 'user', content: 'What laptop should I buy?' },
110
- * { role: 'assistant', content: 'What is your budget?' }
111
- * ],
112
- * sessionId: 'session-123',
113
- * placements: [{ placement: 'below_response' }],
114
- * userId: 'user-456',
115
- * user: { gender: 'male', age: '25-34' },
116
- * device: { ip: '1.2.3.4', country: 'US' },
117
- * excludedTopics: ['politics'],
118
- * relevancy: 0.5
119
- * };
120
- * ```
103
+ * Extract the end-user's real IP from a server request object.
104
+ * Works with Express, Fastify, Node http, Next.js, and any object with `headers`.
121
105
  */
122
- interface AdParams {
123
- /** Array of conversation messages for contextual targeting (required) */
124
- messages: MessageObject[];
125
- /** Session identifier for ad relevance (required) */
126
- sessionId: string;
127
- /** Ad placement specifications (required). Array of 1-10 placements. */
128
- placements: PlacementObject[];
129
- /** Unique user identifier */
130
- userId?: string;
131
- /** Device and location information */
132
- device?: DeviceObject;
133
- /** User demographic and interest data */
134
- user?: UserObject;
135
- /** Topics to exclude from ad matching (e.g., ['politics', 'religion']) */
136
- excludedTopics?: string[];
137
- /** Minimum relevancy score threshold (0-1). Higher = more relevant but fewer ads */
138
- relevancy?: number | null;
139
- /** Returns a test ad when true (no billing, for integration testing) */
140
- testAd?: boolean;
141
- /**
142
- * Additional custom fields for publisher-specific targeting
143
- * @description Any additional key-value pairs will be passed to the API
144
- */
145
- [key: string]: unknown;
146
- }
106
+ declare function extractClientIp(req: IncomingAdRequest): string | undefined;
147
107
  /**
148
- * Single ad object in responses.
149
- * @description Contains ad creative and tracking data. Returned as a flat array from v1 API.
150
- * @example
151
- * ```typescript
152
- * const ad: Ad = {
153
- * adText: 'Check out our amazing laptops!',
154
- * title: 'Dell XPS 15',
155
- * cta: 'Shop Now',
156
- * brandName: 'Dell',
157
- * url: 'https://dell.com/xps',
158
- * impUrl: 'https://tracking.example.com/imp?id=123',
159
- * clickUrl: 'https://tracking.example.com/click?id=123'
160
- * };
108
+ * Fetch ads from the Gravity API. **Never throws.**
109
+ *
110
+ * Reads `gravity_context` from `req.body` (sent by the client via `gravityContext()`),
111
+ * extracts the end-user's IP from request headers, and calls the Gravity ad endpoint.
112
+ *
113
+ * The publisher just passes `req` through — no manual IP extraction or context
114
+ * forwarding needed.
115
+ *
116
+ * @param req - The server request object (Express, Fastify, Node http, Next.js, etc.)
117
+ * @param messages - Conversation messages `[{ role, content }]` — last 2 turns are sent
118
+ * @param placements - Ad placements, e.g. `[{ placement: "below_response", placement_id: "main" }]`
119
+ * @param opts - API key, timeout, relevancy, testAd, etc.
120
+ * @returns `{ ads, status, elapsed, requestBody, error? }` — always resolves
121
+ *
122
+ * @example Express
123
+ * ```ts
124
+ * import { gravityAds } from '@gravity-ai/api';
125
+ *
126
+ * app.post('/api/chat', async (req, res) => {
127
+ * const { messages } = req.body;
128
+ *
129
+ * const adPromise = gravityAds(req, messages, [
130
+ * { placement: 'below_response', placement_id: 'main' },
131
+ * ]);
132
+ *
133
+ * // stream your LLM response...
134
+ *
135
+ * const { ads } = await adPromise;
136
+ * res.write(`data: ${JSON.stringify({ type: 'done', ads })}\n\n`);
137
+ * res.end();
138
+ * });
139
+ * ```
140
+ *
141
+ * @example Next.js Route Handler
142
+ * ```ts
143
+ * import { gravityAds } from '@gravity-ai/api';
144
+ *
145
+ * export async function POST(request: Request) {
146
+ * const body = await request.json();
147
+ * const { ads } = await gravityAds(
148
+ * { body, headers: Object.fromEntries(request.headers) },
149
+ * body.messages,
150
+ * [{ placement: 'below_response', placement_id: 'main' }],
151
+ * );
152
+ * return Response.json({ ads });
153
+ * }
161
154
  * ```
162
155
  */
163
- interface Ad {
164
- /** The advertisement copy text */
165
- adText: string;
166
- /** Ad title */
167
- title?: string;
168
- /** Call-to-action text (e.g., 'Learn More', 'Shop Now') */
169
- cta?: string;
170
- /** Brand/advertiser name */
171
- brandName?: string;
172
- /** Landing page URL */
173
- url?: string;
174
- /** Favicon URL */
175
- favicon?: string;
176
- /** Impression tracking URL - fire this when ad is displayed */
177
- impUrl?: string;
178
- /** Click-through tracking URL - use this as href for ad clicks */
179
- clickUrl?: string;
180
- }
181
- /**
182
- * Error response structure from the Gravity API
183
- * @description Returned when the API encounters an error processing the request
184
- */
185
- interface ApiErrorResponse {
186
- /** Error code or type identifier */
187
- error: string;
188
- /** Human-readable error description */
189
- message?: string;
190
- /** HTTP status code */
191
- statusCode?: number;
192
- }
156
+ declare function gravityAds(req: IncomingAdRequest, messages: MessageObject[], placements: PlacementObject[], opts?: GravityAdsOptions): Promise<GravityAdsResult>;
193
157
 
194
158
  /**
195
- * Configuration options for the Gravity API Client
196
- * @description Pass these options when creating a new Client instance
197
- * @example
198
- * ```typescript
199
- * const params: ClientParams = {
200
- * endpoint: 'https://custom.gravity.server',
201
- * excludedTopics: ['politics', 'religion'],
202
- * relevancy: 0.5
203
- * };
204
- * ```
159
+ * @deprecated Use `Gravity` instead. See README for migration guide.
205
160
  */
206
161
  interface ClientParams {
207
162
  /**
@@ -223,37 +178,13 @@ interface ClientParams {
223
178
  relevancy?: number | null;
224
179
  }
225
180
  /**
226
- * Gravity API Client
181
+ * @deprecated Use `Gravity` instead — it reads the API key from env, auto-extracts
182
+ * client context and IP from the request, and pairs with `gravityContext()` on the client.
227
183
  *
228
- * @description The main client for interacting with the Gravity AI advertising API.
229
- * Use this client to fetch contextually relevant advertisements based on conversation content.
230
- *
231
- * @example Basic usage
232
- * ```typescript
233
- * import { Client } from '@gravity-ai/api';
234
- *
235
- * const client = new Client('your-api-key');
236
- *
237
- * const ads = await client.getAd({
238
- * messages: [
239
- * { role: 'user', content: 'What laptop should I buy?' }
240
- * ],
241
- * sessionId: 'session-123',
242
- * placements: [{ placement: 'below_response' }]
243
- * });
244
- *
245
- * if (ads) {
246
- * console.log(ads[0].adText);
247
- * }
248
- * ```
249
- *
250
- * @example With configuration options
251
- * ```typescript
252
- * const client = new Client('your-api-key', {
253
- * endpoint: 'https://custom.server.com',
254
- * excludedTopics: ['politics'],
255
- * relevancy: 0.7
256
- * });
184
+ * ```ts
185
+ * import { Gravity } from '@gravity-ai/api';
186
+ * const gravity = new Gravity({ production: true });
187
+ * const { ads } = await gravity.getAds(req, messages, placements);
257
188
  * ```
258
189
  */
259
190
  declare class Client {
@@ -361,4 +292,4 @@ declare class Client {
361
292
  private handleError;
362
293
  }
363
294
 
364
- export { type Ad, type AdParams, type ApiErrorResponse, Client, type ClientParams, type DeviceObject, type Gender, type MessageObject, type Placement, type PlacementObject, type Role, type UserObject };
295
+ export { Ad, AdParams, Client, type ClientParams, Gravity, GravityAdsOptions, GravityAdsResult, GravityContext, GravityContextOverrides, IncomingAdRequest, MessageObject, PlacementObject, extractClientIp, gravityAds, gravityContext, toGravityMessages };