@adzenai/ai 1.1.0 → 1.2.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.
@@ -1,19 +1,31 @@
1
1
  import * as react from 'react';
2
- import { AdzenPlacement } from '@adzenai/core';
2
+ import { InlineAdEvent, AdzenPlacement, InlineAdEventPayload } from '@adzenai/core';
3
3
 
4
4
  interface AdzenCardProps {
5
5
  messageId: string;
6
6
  adUnitPosition?: string;
7
7
  viewabilityThresholdMs?: number;
8
8
  className?: string;
9
- /** Relative path on the integrator's server that proxies impression calls. */
10
- impressionProxyPath?: string;
11
9
  }
12
10
  /**
13
11
  * Renders a sponsored ad card for a given assistant message. Returns `null`
14
12
  * (no DOM output) when there is no ad for the message.
15
13
  */
16
- declare function AdzenCard({ messageId, adUnitPosition, viewabilityThresholdMs, className, impressionProxyPath, }: AdzenCardProps): react.JSX.Element | null;
14
+ declare function AdzenCard({ messageId, adUnitPosition, viewabilityThresholdMs, className, }: AdzenCardProps): react.JSX.Element | null;
15
+
16
+ interface InlineAdProps {
17
+ ad: InlineAdEvent;
18
+ viewabilityThresholdMs?: number;
19
+ className?: string;
20
+ }
21
+ /**
22
+ * Renders an inline ad as a single line of text — an "Ad" pill, the advertiser
23
+ * name, and the CTA as the only link — rather than a card, so it sits in the
24
+ * message body without competing with the assistant's own content.
25
+ *
26
+ * Tracks render/view impressions via the same beacon pattern as AdzenCard.
27
+ */
28
+ declare function InlineAd({ ad, viewabilityThresholdMs, className, }: InlineAdProps): react.JSX.Element;
17
29
 
18
30
  interface UseAdzenPlacementReturn {
19
31
  getAdForMessage(messageId: string): AdzenPlacement | null;
@@ -28,20 +40,62 @@ interface UseAdzenPlacementReturn {
28
40
  */
29
41
  declare function useAdzenPlacement(): UseAdzenPlacementReturn;
30
42
 
43
+ /** A run of message text, or an ad anchored to the end of the run before it. */
44
+ type InlineAdSegment = {
45
+ kind: "text";
46
+ text: string;
47
+ } | {
48
+ kind: "ad";
49
+ ad: InlineAdEventPayload;
50
+ };
51
+ interface UseAdzenInlineAdsReturn {
52
+ getInlineAdsForMessage(messageId: string): InlineAdEventPayload[];
53
+ getInlineAdSegments(messageId: string, content: string): InlineAdSegment[];
54
+ }
55
+ /**
56
+ * Splits `content` into text and ad segments, placing each ad after the text
57
+ * that had streamed when it arrived.
58
+ *
59
+ * At most one ad is placed per paragraph break. Several ads routinely resolve
60
+ * to the same break — the API can emit a burst of them, and every ad anchored
61
+ * inside one paragraph snaps to that paragraph's end — so each ad after the
62
+ * first is moved to the next free break, with the end of the content usable as
63
+ * a final slot. An ad with no free slot is left out and appears once the
64
+ * message has grown enough to hold it, which keeps ads from piling up in one
65
+ * spot while a paragraph is still streaming.
66
+ *
67
+ * @param ads Must be sorted by `content_offset` ascending.
68
+ */
69
+ declare function buildInlineAdSegments(content: string, ads: InlineAdEventPayload[]): InlineAdSegment[];
70
+ /**
71
+ * React hook that subscribes to `adzen_inline_ad` custom events on
72
+ * `window` and maintains a map of messageId -> InlineAdEventPayload[].
73
+ *
74
+ * Supports multiple inline ads per message per the cardinality requirements.
75
+ * Ads are kept sorted by `content_offset` so they can be interleaved with the
76
+ * message text at the point in the stream where they arrived.
77
+ */
78
+ declare function useAdzenInlineAds(): UseAdzenInlineAdsReturn;
79
+
31
80
  /**
32
81
  * Checks whether an AG-UI event is an `adzen_placement` custom event
33
82
  * and, if so, dispatches it as a browser `CustomEvent` on `window`
34
83
  * so that `useAdzenPlacement` can pick it up.
35
84
  *
36
- * Call this for every event returned by `AdzenAsyncMiddleware.processEvent()`.
37
- * Non-placement events are silently ignored.
85
+ * Call this for every event returned by middleware `processEvent()` or
86
+ * `processStream()`. Non-placement events are silently ignored.
38
87
  */
39
88
  declare function dispatchPlacementEvent(event: Record<string, unknown>): boolean;
40
89
  /**
41
- * Convenience wrapper: iterates an array of AG-UI events (as returned by
42
- * `AdzenAsyncMiddleware.processEvent()`) and dispatches any placement
43
- * events to the browser.
90
+ * Checks whether an AG-UI event is an `adzen_inline_ad` custom event
91
+ * and, if so, dispatches it as a browser `CustomEvent` on `window`
92
+ * so that `useAdzenInlineAds` can pick it up.
93
+ */
94
+ declare function dispatchInlineAdEvent(event: Record<string, unknown>): boolean;
95
+ /**
96
+ * Convenience wrapper: iterates an array of AG-UI events and dispatches
97
+ * any placement or inline ad events to the browser.
44
98
  */
45
99
  declare function dispatchPlacementEvents(events: Record<string, unknown>[]): void;
46
100
 
47
- export { AdzenCard, type AdzenCardProps, type UseAdzenPlacementReturn, dispatchPlacementEvent, dispatchPlacementEvents, useAdzenPlacement };
101
+ export { AdzenCard, type AdzenCardProps, InlineAd, type InlineAdProps, type InlineAdSegment, type UseAdzenInlineAdsReturn, type UseAdzenPlacementReturn, buildInlineAdSegments, dispatchInlineAdEvent, dispatchPlacementEvent, dispatchPlacementEvents, useAdzenInlineAds, useAdzenPlacement };
@@ -1,19 +1,31 @@
1
1
  import * as react from 'react';
2
- import { AdzenPlacement } from '@adzenai/core';
2
+ import { InlineAdEvent, AdzenPlacement, InlineAdEventPayload } from '@adzenai/core';
3
3
 
4
4
  interface AdzenCardProps {
5
5
  messageId: string;
6
6
  adUnitPosition?: string;
7
7
  viewabilityThresholdMs?: number;
8
8
  className?: string;
9
- /** Relative path on the integrator's server that proxies impression calls. */
10
- impressionProxyPath?: string;
11
9
  }
12
10
  /**
13
11
  * Renders a sponsored ad card for a given assistant message. Returns `null`
14
12
  * (no DOM output) when there is no ad for the message.
15
13
  */
16
- declare function AdzenCard({ messageId, adUnitPosition, viewabilityThresholdMs, className, impressionProxyPath, }: AdzenCardProps): react.JSX.Element | null;
14
+ declare function AdzenCard({ messageId, adUnitPosition, viewabilityThresholdMs, className, }: AdzenCardProps): react.JSX.Element | null;
15
+
16
+ interface InlineAdProps {
17
+ ad: InlineAdEvent;
18
+ viewabilityThresholdMs?: number;
19
+ className?: string;
20
+ }
21
+ /**
22
+ * Renders an inline ad as a single line of text — an "Ad" pill, the advertiser
23
+ * name, and the CTA as the only link — rather than a card, so it sits in the
24
+ * message body without competing with the assistant's own content.
25
+ *
26
+ * Tracks render/view impressions via the same beacon pattern as AdzenCard.
27
+ */
28
+ declare function InlineAd({ ad, viewabilityThresholdMs, className, }: InlineAdProps): react.JSX.Element;
17
29
 
18
30
  interface UseAdzenPlacementReturn {
19
31
  getAdForMessage(messageId: string): AdzenPlacement | null;
@@ -28,20 +40,62 @@ interface UseAdzenPlacementReturn {
28
40
  */
29
41
  declare function useAdzenPlacement(): UseAdzenPlacementReturn;
30
42
 
43
+ /** A run of message text, or an ad anchored to the end of the run before it. */
44
+ type InlineAdSegment = {
45
+ kind: "text";
46
+ text: string;
47
+ } | {
48
+ kind: "ad";
49
+ ad: InlineAdEventPayload;
50
+ };
51
+ interface UseAdzenInlineAdsReturn {
52
+ getInlineAdsForMessage(messageId: string): InlineAdEventPayload[];
53
+ getInlineAdSegments(messageId: string, content: string): InlineAdSegment[];
54
+ }
55
+ /**
56
+ * Splits `content` into text and ad segments, placing each ad after the text
57
+ * that had streamed when it arrived.
58
+ *
59
+ * At most one ad is placed per paragraph break. Several ads routinely resolve
60
+ * to the same break — the API can emit a burst of them, and every ad anchored
61
+ * inside one paragraph snaps to that paragraph's end — so each ad after the
62
+ * first is moved to the next free break, with the end of the content usable as
63
+ * a final slot. An ad with no free slot is left out and appears once the
64
+ * message has grown enough to hold it, which keeps ads from piling up in one
65
+ * spot while a paragraph is still streaming.
66
+ *
67
+ * @param ads Must be sorted by `content_offset` ascending.
68
+ */
69
+ declare function buildInlineAdSegments(content: string, ads: InlineAdEventPayload[]): InlineAdSegment[];
70
+ /**
71
+ * React hook that subscribes to `adzen_inline_ad` custom events on
72
+ * `window` and maintains a map of messageId -> InlineAdEventPayload[].
73
+ *
74
+ * Supports multiple inline ads per message per the cardinality requirements.
75
+ * Ads are kept sorted by `content_offset` so they can be interleaved with the
76
+ * message text at the point in the stream where they arrived.
77
+ */
78
+ declare function useAdzenInlineAds(): UseAdzenInlineAdsReturn;
79
+
31
80
  /**
32
81
  * Checks whether an AG-UI event is an `adzen_placement` custom event
33
82
  * and, if so, dispatches it as a browser `CustomEvent` on `window`
34
83
  * so that `useAdzenPlacement` can pick it up.
35
84
  *
36
- * Call this for every event returned by `AdzenAsyncMiddleware.processEvent()`.
37
- * Non-placement events are silently ignored.
85
+ * Call this for every event returned by middleware `processEvent()` or
86
+ * `processStream()`. Non-placement events are silently ignored.
38
87
  */
39
88
  declare function dispatchPlacementEvent(event: Record<string, unknown>): boolean;
40
89
  /**
41
- * Convenience wrapper: iterates an array of AG-UI events (as returned by
42
- * `AdzenAsyncMiddleware.processEvent()`) and dispatches any placement
43
- * events to the browser.
90
+ * Checks whether an AG-UI event is an `adzen_inline_ad` custom event
91
+ * and, if so, dispatches it as a browser `CustomEvent` on `window`
92
+ * so that `useAdzenInlineAds` can pick it up.
93
+ */
94
+ declare function dispatchInlineAdEvent(event: Record<string, unknown>): boolean;
95
+ /**
96
+ * Convenience wrapper: iterates an array of AG-UI events and dispatches
97
+ * any placement or inline ad events to the browser.
44
98
  */
45
99
  declare function dispatchPlacementEvents(events: Record<string, unknown>[]): void;
46
100
 
47
- export { AdzenCard, type AdzenCardProps, type UseAdzenPlacementReturn, dispatchPlacementEvent, dispatchPlacementEvents, useAdzenPlacement };
101
+ export { AdzenCard, type AdzenCardProps, InlineAd, type InlineAdProps, type InlineAdSegment, type UseAdzenInlineAdsReturn, type UseAdzenPlacementReturn, buildInlineAdSegments, dispatchInlineAdEvent, dispatchPlacementEvent, dispatchPlacementEvents, useAdzenInlineAds, useAdzenPlacement };
@@ -37,19 +37,10 @@ function useAdzenPlacement() {
37
37
 
38
38
  // src/copilotkit/react/AdzenCard.tsx
39
39
  import { jsx, jsxs } from "react/jsx-runtime";
40
- var DEFAULT_PROXY_PATH = "/api/adzen/impressions";
41
- function fireBeacon(url, body) {
42
- fetch(url, {
43
- method: "POST",
44
- headers: { "Content-Type": "application/json" },
45
- body
46
- }).catch(() => {
40
+ function fireBeacon(url) {
41
+ fetch(url, { method: "GET", keepalive: true }).catch(() => {
47
42
  setTimeout(() => {
48
- fetch(url, {
49
- method: "POST",
50
- headers: { "Content-Type": "application/json" },
51
- body
52
- }).catch(() => {
43
+ fetch(url, { method: "GET", keepalive: true }).catch(() => {
53
44
  });
54
45
  }, 1e3);
55
46
  });
@@ -58,8 +49,7 @@ function AdzenCard({
58
49
  messageId,
59
50
  adUnitPosition = "chin",
60
51
  viewabilityThresholdMs = 1e3,
61
- className,
62
- impressionProxyPath = DEFAULT_PROXY_PATH
52
+ className
63
53
  }) {
64
54
  const { getAdForMessage } = useAdzenPlacement();
65
55
  const ad = getAdForMessage(messageId);
@@ -67,40 +57,29 @@ function AdzenCard({
67
57
  const [renderFired, setRenderFired] = useState2(false);
68
58
  const [viewed, setViewed] = useState2(false);
69
59
  useEffect2(() => {
70
- if (!ad || renderFired) return;
60
+ if (!ad || renderFired || !ad.render_impression_url) return;
71
61
  setRenderFired(true);
72
- fireBeacon(
73
- impressionProxyPath,
74
- JSON.stringify({
75
- type: "render",
76
- ad_id: ad.ad_id,
77
- message_id: messageId,
78
- ad_unit_position: adUnitPosition,
79
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
80
- })
81
- );
82
- }, [ad, renderFired, messageId, adUnitPosition, impressionProxyPath]);
62
+ const url = new URL(ad.render_impression_url);
63
+ url.searchParams.set("ad_unit_position", adUnitPosition);
64
+ url.searchParams.set("timestamp", (/* @__PURE__ */ new Date()).toISOString());
65
+ fireBeacon(url.toString());
66
+ }, [ad, renderFired, adUnitPosition]);
83
67
  useEffect2(() => {
84
- if (!ad || !cardRef.current || viewed) return;
68
+ if (!ad || !cardRef.current || viewed || !ad.view_impression_url) return;
85
69
  return observeViewability({
86
70
  element: cardRef.current,
87
71
  thresholdMs: viewabilityThresholdMs,
88
72
  onViewed: () => {
89
73
  setViewed(true);
90
- fireBeacon(
91
- impressionProxyPath,
92
- JSON.stringify({
93
- type: "view",
94
- ad_id: ad.ad_id,
95
- message_id: messageId,
96
- ad_unit_position: adUnitPosition,
97
- viewability_ms: viewabilityThresholdMs,
98
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
99
- })
100
- );
74
+ if (!ad.view_impression_url) return;
75
+ const url = new URL(ad.view_impression_url);
76
+ url.searchParams.set("ad_unit_position", adUnitPosition);
77
+ url.searchParams.set("viewability_ms", String(viewabilityThresholdMs));
78
+ url.searchParams.set("timestamp", (/* @__PURE__ */ new Date()).toISOString());
79
+ fireBeacon(url.toString());
101
80
  }
102
81
  });
103
- }, [ad, viewed, messageId, adUnitPosition, viewabilityThresholdMs, impressionProxyPath]);
82
+ }, [ad, viewed, adUnitPosition, viewabilityThresholdMs]);
104
83
  if (!ad) return null;
105
84
  const initial = ad.advertiser_name?.charAt(0).toUpperCase() ?? "?";
106
85
  return /* @__PURE__ */ jsxs(
@@ -212,13 +191,194 @@ var cardStyles = {
212
191
  }
213
192
  };
214
193
 
194
+ // src/copilotkit/react/InlineAd.tsx
195
+ import { useRef as useRef2, useEffect as useEffect3, useState as useState3 } from "react";
196
+ import { observeViewability as observeViewability2 } from "@adzenai/core";
197
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
198
+ function fireBeacon2(url) {
199
+ fetch(url, { method: "GET", keepalive: true }).catch(() => {
200
+ setTimeout(() => {
201
+ fetch(url, { method: "GET", keepalive: true }).catch(() => {
202
+ });
203
+ }, 1e3);
204
+ });
205
+ }
206
+ function InlineAd({
207
+ ad,
208
+ viewabilityThresholdMs = 1e3,
209
+ className
210
+ }) {
211
+ const ref = useRef2(null);
212
+ const [renderFired, setRenderFired] = useState3(false);
213
+ const [viewed, setViewed] = useState3(false);
214
+ useEffect3(() => {
215
+ if (renderFired || !ad.tracking.impression_url) return;
216
+ setRenderFired(true);
217
+ const url = new URL(ad.tracking.impression_url);
218
+ url.searchParams.set("timestamp", (/* @__PURE__ */ new Date()).toISOString());
219
+ fireBeacon2(url.toString());
220
+ }, [ad, renderFired]);
221
+ useEffect3(() => {
222
+ if (!ref.current || viewed || !ad.tracking.impression_url) return;
223
+ return observeViewability2({
224
+ element: ref.current,
225
+ thresholdMs: viewabilityThresholdMs,
226
+ onViewed: () => {
227
+ setViewed(true);
228
+ if (!ad.tracking.impression_url) return;
229
+ const url = new URL(ad.tracking.impression_url);
230
+ url.searchParams.set("type", "view");
231
+ url.searchParams.set("viewability_ms", String(viewabilityThresholdMs));
232
+ url.searchParams.set("timestamp", (/* @__PURE__ */ new Date()).toISOString());
233
+ fireBeacon2(url.toString());
234
+ }
235
+ });
236
+ }, [ad, viewed, viewabilityThresholdMs]);
237
+ const advertiser = ad.creative.advertiser_name ?? ad.creative.headline;
238
+ return /* @__PURE__ */ jsxs2("div", { ref, className, style: inlineStyles.wrapper, children: [
239
+ /* @__PURE__ */ jsx2("span", { style: inlineStyles.badge, "aria-label": "Advertisement", children: "Ad" }),
240
+ advertiser ? /* @__PURE__ */ jsxs2("span", { style: inlineStyles.advertiser, children: [
241
+ advertiser,
242
+ " "
243
+ ] }) : null,
244
+ /* @__PURE__ */ jsx2(
245
+ "a",
246
+ {
247
+ href: ad.creative.destination_url,
248
+ target: "_blank",
249
+ rel: "noopener sponsored",
250
+ style: inlineStyles.cta,
251
+ children: ad.creative.cta_text
252
+ }
253
+ )
254
+ ] });
255
+ }
256
+ var inlineStyles = {
257
+ // Block-level so the snippet starts on its own line below the text it
258
+ // follows, but otherwise plain: no border, background, or padding.
259
+ wrapper: {
260
+ display: "block",
261
+ margin: "0.5rem 0",
262
+ fontSize: "0.9em",
263
+ lineHeight: 1.5
264
+ },
265
+ badge: {
266
+ display: "inline-block",
267
+ marginRight: "0.4em",
268
+ padding: "0.1em 0.4em",
269
+ borderRadius: 4,
270
+ background: "#30363d",
271
+ color: "#8b949e",
272
+ fontSize: "0.75em",
273
+ fontWeight: 700,
274
+ letterSpacing: "0.05em",
275
+ textTransform: "uppercase",
276
+ verticalAlign: "middle"
277
+ },
278
+ advertiser: {
279
+ color: "#8b949e"
280
+ },
281
+ cta: {
282
+ color: "#58a6ff",
283
+ textDecoration: "none",
284
+ fontWeight: 500
285
+ }
286
+ };
287
+
288
+ // src/copilotkit/react/useAdzenInlineAds.ts
289
+ import { useState as useState4, useEffect as useEffect4, useCallback as useCallback2 } from "react";
290
+ function readOffset(payload) {
291
+ return typeof payload.content_offset === "number" ? payload.content_offset : Number.MAX_SAFE_INTEGER;
292
+ }
293
+ var PARAGRAPH_BREAK = /\n[ \t]*\n/;
294
+ var ENDS_ON_PARAGRAPH_BREAK = /\n[ \t]*\n$/;
295
+ function snapToParagraphEnd(content, offset) {
296
+ if (offset >= content.length) return content.length;
297
+ if (ENDS_ON_PARAGRAPH_BREAK.test(content.slice(0, offset))) return offset;
298
+ return nextParagraphEnd(content, Math.max(0, offset - 1));
299
+ }
300
+ function nextParagraphEnd(content, from) {
301
+ if (from >= content.length) return content.length;
302
+ const match = PARAGRAPH_BREAK.exec(content.slice(from));
303
+ return match ? from + match.index + match[0].length : content.length;
304
+ }
305
+ function buildInlineAdSegments(content, ads) {
306
+ if (ads.length === 0) {
307
+ return content ? [{ kind: "text", text: content }] : [];
308
+ }
309
+ const segments = [];
310
+ let cursor = 0;
311
+ let lastAnchor = -1;
312
+ for (const ad of ads) {
313
+ let anchor = snapToParagraphEnd(content, Math.max(ad.content_offset, 0));
314
+ if (anchor <= lastAnchor) anchor = nextParagraphEnd(content, lastAnchor);
315
+ if (anchor <= lastAnchor) continue;
316
+ if (anchor > cursor) {
317
+ segments.push({ kind: "text", text: content.slice(cursor, anchor) });
318
+ }
319
+ segments.push({ kind: "ad", ad });
320
+ cursor = anchor;
321
+ lastAnchor = anchor;
322
+ }
323
+ if (cursor < content.length) {
324
+ segments.push({ kind: "text", text: content.slice(cursor) });
325
+ }
326
+ return segments;
327
+ }
328
+ function useAdzenInlineAds() {
329
+ const [adsMap, setAdsMap] = useState4(
330
+ () => /* @__PURE__ */ new Map()
331
+ );
332
+ useEffect4(() => {
333
+ function handler(e) {
334
+ const detail = e.detail;
335
+ if (!detail || typeof detail !== "object") return;
336
+ const payload = detail;
337
+ const messageId = payload.message_id;
338
+ if (!messageId) return;
339
+ const anchored = {
340
+ ...payload,
341
+ message_id: messageId,
342
+ content_offset: readOffset(payload)
343
+ };
344
+ setAdsMap((prev) => {
345
+ const existing = prev.get(messageId) ?? [];
346
+ if (existing.some((a) => a.ad_id === anchored.ad_id)) return prev;
347
+ const next = new Map(prev);
348
+ next.set(
349
+ messageId,
350
+ [...existing, anchored].sort(
351
+ (a, b) => a.content_offset - b.content_offset
352
+ )
353
+ );
354
+ return next;
355
+ });
356
+ }
357
+ window.addEventListener("adzen_inline_ad", handler);
358
+ return () => window.removeEventListener("adzen_inline_ad", handler);
359
+ }, []);
360
+ const getInlineAdsForMessage = useCallback2(
361
+ (messageId) => {
362
+ return adsMap.get(messageId) ?? [];
363
+ },
364
+ [adsMap]
365
+ );
366
+ const getInlineAdSegments = useCallback2(
367
+ (messageId, content) => buildInlineAdSegments(content, adsMap.get(messageId) ?? []),
368
+ [adsMap]
369
+ );
370
+ return { getInlineAdsForMessage, getInlineAdSegments };
371
+ }
372
+
215
373
  // src/copilotkit/react/bridge.ts
374
+ function isCustomEvent(event) {
375
+ const type = String(event.type ?? "");
376
+ return type === "CUSTOM_EVENT" || type === "CUSTOM" || type === "CustomEvent";
377
+ }
216
378
  function dispatchPlacementEvent(event) {
217
379
  if (typeof window === "undefined") return false;
218
380
  if (event.name !== "adzen_placement") return false;
219
- const type = String(event.type ?? "");
220
- if (type !== "CUSTOM_EVENT" && type !== "CUSTOM" && type !== "CustomEvent")
221
- return false;
381
+ if (!isCustomEvent(event)) return false;
222
382
  const value = event.value;
223
383
  if (!value) return false;
224
384
  window.dispatchEvent(
@@ -226,15 +386,31 @@ function dispatchPlacementEvent(event) {
226
386
  );
227
387
  return true;
228
388
  }
389
+ function dispatchInlineAdEvent(event) {
390
+ if (typeof window === "undefined") return false;
391
+ if (event.name !== "adzen_inline_ad") return false;
392
+ if (!isCustomEvent(event)) return false;
393
+ const value = event.value;
394
+ if (!value) return false;
395
+ window.dispatchEvent(
396
+ new CustomEvent("adzen_inline_ad", { detail: value })
397
+ );
398
+ return true;
399
+ }
229
400
  function dispatchPlacementEvents(events) {
230
401
  for (const event of events) {
231
402
  dispatchPlacementEvent(event);
403
+ dispatchInlineAdEvent(event);
232
404
  }
233
405
  }
234
406
  export {
235
407
  AdzenCard,
408
+ InlineAd,
409
+ buildInlineAdSegments,
410
+ dispatchInlineAdEvent,
236
411
  dispatchPlacementEvent,
237
412
  dispatchPlacementEvents,
413
+ useAdzenInlineAds,
238
414
  useAdzenPlacement
239
415
  };
240
416
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/copilotkit/react/AdzenCard.tsx","../../../src/copilotkit/react/useAdzenPlacement.ts","../../../src/copilotkit/react/bridge.ts"],"sourcesContent":["import { useRef, useEffect, useState } from \"react\";\nimport { observeViewability } from \"@adzenai/core\";\nimport { useAdzenPlacement } from \"./useAdzenPlacement.js\";\n\nexport interface AdzenCardProps {\n messageId: string;\n adUnitPosition?: string;\n viewabilityThresholdMs?: number;\n className?: string;\n /** Relative path on the integrator's server that proxies impression calls. */\n impressionProxyPath?: string;\n}\n\nconst DEFAULT_PROXY_PATH = \"/api/adzen/impressions\";\n\nfunction fireBeacon(url: string, body: string): void {\n fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n }).catch(() => {\n setTimeout(() => {\n fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n }).catch(() => {});\n }, 1000);\n });\n}\n\n/**\n * Renders a sponsored ad card for a given assistant message. Returns `null`\n * (no DOM output) when there is no ad for the message.\n */\nexport function AdzenCard({\n messageId,\n adUnitPosition = \"chin\",\n viewabilityThresholdMs = 1000,\n className,\n impressionProxyPath = DEFAULT_PROXY_PATH,\n}: AdzenCardProps) {\n const { getAdForMessage } = useAdzenPlacement();\n const ad = getAdForMessage(messageId);\n const cardRef = useRef<HTMLDivElement>(null);\n const [renderFired, setRenderFired] = useState(false);\n const [viewed, setViewed] = useState(false);\n\n useEffect(() => {\n if (!ad || renderFired) return;\n setRenderFired(true);\n\n fireBeacon(\n impressionProxyPath,\n JSON.stringify({\n type: \"render\",\n ad_id: ad.ad_id,\n message_id: messageId,\n ad_unit_position: adUnitPosition,\n timestamp: new Date().toISOString(),\n }),\n );\n }, [ad, renderFired, messageId, adUnitPosition, impressionProxyPath]);\n\n useEffect(() => {\n if (!ad || !cardRef.current || viewed) return;\n\n return observeViewability({\n element: cardRef.current,\n thresholdMs: viewabilityThresholdMs,\n onViewed: () => {\n setViewed(true);\n fireBeacon(\n impressionProxyPath,\n JSON.stringify({\n type: \"view\",\n ad_id: ad.ad_id,\n message_id: messageId,\n ad_unit_position: adUnitPosition,\n viewability_ms: viewabilityThresholdMs,\n timestamp: new Date().toISOString(),\n }),\n );\n },\n });\n }, [ad, viewed, messageId, adUnitPosition, viewabilityThresholdMs, impressionProxyPath]);\n\n if (!ad) return null;\n\n const initial = ad.advertiser_name?.charAt(0).toUpperCase() ?? \"?\";\n\n return (\n <div\n ref={cardRef}\n className={className}\n data-adzen-ad-unit-position={adUnitPosition}\n style={cardStyles.wrapper}\n >\n <div style={cardStyles.avatar}>\n {ad.advertiser_image_url ? (\n <img\n src={ad.advertiser_image_url}\n alt={ad.advertiser_name}\n style={cardStyles.avatarImg}\n />\n ) : (\n <span style={cardStyles.avatarLetter}>{initial}</span>\n )}\n </div>\n\n <div style={cardStyles.content}>\n <div style={cardStyles.topRow}>\n <span style={cardStyles.advertiserName}>{ad.advertiser_name}</span>\n <span style={cardStyles.relevantAd}>Relevant Ad</span>\n </div>\n <div style={cardStyles.bottomRow}>\n <span style={cardStyles.headline}>{ad.headline}</span>\n <a\n href={ad.destination_url}\n target=\"_blank\"\n rel=\"noopener sponsored\"\n style={cardStyles.cta}\n >\n {ad.cta_text}\n </a>\n </div>\n </div>\n </div>\n );\n}\n\nconst cardStyles: Record<string, React.CSSProperties> = {\n wrapper: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.625rem\",\n fontSize: \"0.85rem\",\n padding: \"0.625rem 0.75rem\",\n },\n avatar: {\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n background: \"#d1d5db\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n overflow: \"hidden\",\n },\n avatarImg: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\" as const,\n borderRadius: \"50%\",\n },\n avatarLetter: {\n fontSize: \"0.8rem\",\n fontWeight: 700,\n color: \"#374151\",\n lineHeight: 1,\n },\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"0.125rem\",\n minWidth: 0,\n },\n topRow: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n },\n advertiserName: {\n fontWeight: 700,\n color: \"inherit\",\n },\n relevantAd: {\n color: \"#8b949e\",\n fontSize: \"0.8rem\",\n },\n bottomRow: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n whiteSpace: \"nowrap\" as const,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n },\n headline: {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n },\n cta: {\n color: \"#58a6ff\",\n textDecoration: \"none\",\n fontWeight: 500,\n flexShrink: 0,\n },\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport type { AdzenPlacement } from \"@adzenai/core\";\n\nexport interface UseAdzenPlacementReturn {\n getAdForMessage(messageId: string): AdzenPlacement | null;\n placements: Map<string, AdzenPlacement>;\n}\n\n/**\n * React hook that subscribes to `adzen_placement` custom events and\n * maintains a map of messageId -> AdzenPlacement.\n *\n * Works anywhere in the React tree below `<CopilotKit>` — no wrapper\n * provider required.\n */\nexport function useAdzenPlacement(): UseAdzenPlacementReturn {\n const [placements, setPlacements] = useState<Map<string, AdzenPlacement>>(\n () => new Map(),\n );\n\n useEffect(() => {\n function handler(e: Event) {\n const detail = (e as CustomEvent).detail;\n if (!detail || typeof detail !== \"object\") return;\n\n const placement = detail as AdzenPlacement & { message_id?: string };\n const messageId = placement.message_id;\n if (!messageId) return;\n\n setPlacements((prev) => {\n const existing = prev.get(messageId);\n if (existing && existing.ad_id === placement.ad_id) return prev;\n const next = new Map(prev);\n next.set(messageId, placement);\n return next;\n });\n }\n\n window.addEventListener(\"adzen_placement\", handler);\n return () => window.removeEventListener(\"adzen_placement\", handler);\n }, []);\n\n const getAdForMessage = useCallback(\n (messageId: string): AdzenPlacement | null => {\n return placements.get(messageId) ?? null;\n },\n [placements],\n );\n\n return { getAdForMessage, placements };\n}\n","import type { AdzenPlacement } from \"@adzenai/core\";\n\n/**\n * Checks whether an AG-UI event is an `adzen_placement` custom event\n * and, if so, dispatches it as a browser `CustomEvent` on `window`\n * so that `useAdzenPlacement` can pick it up.\n *\n * Call this for every event returned by `AdzenAsyncMiddleware.processEvent()`.\n * Non-placement events are silently ignored.\n */\nexport function dispatchPlacementEvent(\n event: Record<string, unknown>,\n): boolean {\n if (typeof window === \"undefined\") return false;\n if (event.name !== \"adzen_placement\") return false;\n\n const type = String(event.type ?? \"\");\n if (type !== \"CUSTOM_EVENT\" && type !== \"CUSTOM\" && type !== \"CustomEvent\")\n return false;\n\n const value = event.value as (AdzenPlacement & { message_id?: string }) | undefined;\n if (!value) return false;\n\n window.dispatchEvent(\n new CustomEvent(\"adzen_placement\", { detail: value }),\n );\n return true;\n}\n\n/**\n * Convenience wrapper: iterates an array of AG-UI events (as returned by\n * `AdzenAsyncMiddleware.processEvent()`) and dispatches any placement\n * events to the browser.\n */\nexport function dispatchPlacementEvents(\n events: Record<string, unknown>[],\n): void {\n for (const event of events) {\n dispatchPlacementEvent(event);\n }\n}\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect"]}
1
+ {"version":3,"sources":["../../../src/copilotkit/react/AdzenCard.tsx","../../../src/copilotkit/react/useAdzenPlacement.ts","../../../src/copilotkit/react/InlineAd.tsx","../../../src/copilotkit/react/useAdzenInlineAds.ts","../../../src/copilotkit/react/bridge.ts"],"sourcesContent":["import { useRef, useEffect, useState } from \"react\";\nimport { observeViewability } from \"@adzenai/core\";\nimport { useAdzenPlacement } from \"./useAdzenPlacement.js\";\n\nexport interface AdzenCardProps {\n messageId: string;\n adUnitPosition?: string;\n viewabilityThresholdMs?: number;\n className?: string;\n}\n\nfunction fireBeacon(url: string): void {\n fetch(url, { method: \"GET\", keepalive: true }).catch(() => {\n setTimeout(() => {\n fetch(url, { method: \"GET\", keepalive: true }).catch(() => {});\n }, 1000);\n });\n}\n\n/**\n * Renders a sponsored ad card for a given assistant message. Returns `null`\n * (no DOM output) when there is no ad for the message.\n */\nexport function AdzenCard({\n messageId,\n adUnitPosition = \"chin\",\n viewabilityThresholdMs = 1000,\n className,\n}: AdzenCardProps) {\n const { getAdForMessage } = useAdzenPlacement();\n const ad = getAdForMessage(messageId);\n const cardRef = useRef<HTMLDivElement>(null);\n const [renderFired, setRenderFired] = useState(false);\n const [viewed, setViewed] = useState(false);\n\n useEffect(() => {\n if (!ad || renderFired || !ad.render_impression_url) return;\n setRenderFired(true);\n\n const url = new URL(ad.render_impression_url);\n url.searchParams.set(\"ad_unit_position\", adUnitPosition);\n url.searchParams.set(\"timestamp\", new Date().toISOString());\n fireBeacon(url.toString());\n }, [ad, renderFired, adUnitPosition]);\n\n useEffect(() => {\n if (!ad || !cardRef.current || viewed || !ad.view_impression_url) return;\n\n return observeViewability({\n element: cardRef.current,\n thresholdMs: viewabilityThresholdMs,\n onViewed: () => {\n setViewed(true);\n if (!ad.view_impression_url) return;\n const url = new URL(ad.view_impression_url);\n url.searchParams.set(\"ad_unit_position\", adUnitPosition);\n url.searchParams.set(\"viewability_ms\", String(viewabilityThresholdMs));\n url.searchParams.set(\"timestamp\", new Date().toISOString());\n fireBeacon(url.toString());\n },\n });\n }, [ad, viewed, adUnitPosition, viewabilityThresholdMs]);\n\n if (!ad) return null;\n\n const initial = ad.advertiser_name?.charAt(0).toUpperCase() ?? \"?\";\n\n return (\n <div\n ref={cardRef}\n className={className}\n data-adzen-ad-unit-position={adUnitPosition}\n style={cardStyles.wrapper}\n >\n <div style={cardStyles.avatar}>\n {ad.advertiser_image_url ? (\n <img\n src={ad.advertiser_image_url}\n alt={ad.advertiser_name}\n style={cardStyles.avatarImg}\n />\n ) : (\n <span style={cardStyles.avatarLetter}>{initial}</span>\n )}\n </div>\n\n <div style={cardStyles.content}>\n <div style={cardStyles.topRow}>\n <span style={cardStyles.advertiserName}>{ad.advertiser_name}</span>\n <span style={cardStyles.relevantAd}>Relevant Ad</span>\n </div>\n <div style={cardStyles.bottomRow}>\n <span style={cardStyles.headline}>{ad.headline}</span>\n <a\n href={ad.destination_url}\n target=\"_blank\"\n rel=\"noopener sponsored\"\n style={cardStyles.cta}\n >\n {ad.cta_text}\n </a>\n </div>\n </div>\n </div>\n );\n}\n\nconst cardStyles: Record<string, React.CSSProperties> = {\n wrapper: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.625rem\",\n fontSize: \"0.85rem\",\n padding: \"0.625rem 0.75rem\",\n },\n avatar: {\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n background: \"#d1d5db\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n overflow: \"hidden\",\n },\n avatarImg: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\" as const,\n borderRadius: \"50%\",\n },\n avatarLetter: {\n fontSize: \"0.8rem\",\n fontWeight: 700,\n color: \"#374151\",\n lineHeight: 1,\n },\n content: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"0.125rem\",\n minWidth: 0,\n },\n topRow: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n },\n advertiserName: {\n fontWeight: 700,\n color: \"inherit\",\n },\n relevantAd: {\n color: \"#8b949e\",\n fontSize: \"0.8rem\",\n },\n bottomRow: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n whiteSpace: \"nowrap\" as const,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n },\n headline: {\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n },\n cta: {\n color: \"#58a6ff\",\n textDecoration: \"none\",\n fontWeight: 500,\n flexShrink: 0,\n },\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport type { AdzenPlacement } from \"@adzenai/core\";\n\nexport interface UseAdzenPlacementReturn {\n getAdForMessage(messageId: string): AdzenPlacement | null;\n placements: Map<string, AdzenPlacement>;\n}\n\n/**\n * React hook that subscribes to `adzen_placement` custom events and\n * maintains a map of messageId -> AdzenPlacement.\n *\n * Works anywhere in the React tree below `<CopilotKit>` — no wrapper\n * provider required.\n */\nexport function useAdzenPlacement(): UseAdzenPlacementReturn {\n const [placements, setPlacements] = useState<Map<string, AdzenPlacement>>(\n () => new Map(),\n );\n\n useEffect(() => {\n function handler(e: Event) {\n const detail = (e as CustomEvent).detail;\n if (!detail || typeof detail !== \"object\") return;\n\n const placement = detail as AdzenPlacement & { message_id?: string };\n const messageId = placement.message_id;\n if (!messageId) return;\n\n setPlacements((prev) => {\n const existing = prev.get(messageId);\n if (existing && existing.ad_id === placement.ad_id) return prev;\n const next = new Map(prev);\n next.set(messageId, placement);\n return next;\n });\n }\n\n window.addEventListener(\"adzen_placement\", handler);\n return () => window.removeEventListener(\"adzen_placement\", handler);\n }, []);\n\n const getAdForMessage = useCallback(\n (messageId: string): AdzenPlacement | null => {\n return placements.get(messageId) ?? null;\n },\n [placements],\n );\n\n return { getAdForMessage, placements };\n}\n","import { useRef, useEffect, useState } from \"react\";\nimport { observeViewability } from \"@adzenai/core\";\nimport type { InlineAdEvent } from \"@adzenai/core\";\n\nexport interface InlineAdProps {\n ad: InlineAdEvent;\n viewabilityThresholdMs?: number;\n className?: string;\n}\n\nfunction fireBeacon(url: string): void {\n fetch(url, { method: \"GET\", keepalive: true }).catch(() => {\n setTimeout(() => {\n fetch(url, { method: \"GET\", keepalive: true }).catch(() => {});\n }, 1000);\n });\n}\n\n/**\n * Renders an inline ad as a single line of text — an \"Ad\" pill, the advertiser\n * name, and the CTA as the only link — rather than a card, so it sits in the\n * message body without competing with the assistant's own content.\n *\n * Tracks render/view impressions via the same beacon pattern as AdzenCard.\n */\nexport function InlineAd({\n ad,\n viewabilityThresholdMs = 1000,\n className,\n}: InlineAdProps) {\n const ref = useRef<HTMLDivElement>(null);\n const [renderFired, setRenderFired] = useState(false);\n const [viewed, setViewed] = useState(false);\n\n useEffect(() => {\n if (renderFired || !ad.tracking.impression_url) return;\n setRenderFired(true);\n\n const url = new URL(ad.tracking.impression_url);\n url.searchParams.set(\"timestamp\", new Date().toISOString());\n fireBeacon(url.toString());\n }, [ad, renderFired]);\n\n useEffect(() => {\n if (!ref.current || viewed || !ad.tracking.impression_url) return;\n\n return observeViewability({\n element: ref.current,\n thresholdMs: viewabilityThresholdMs,\n onViewed: () => {\n setViewed(true);\n if (!ad.tracking.impression_url) return;\n const url = new URL(ad.tracking.impression_url);\n url.searchParams.set(\"type\", \"view\");\n url.searchParams.set(\"viewability_ms\", String(viewabilityThresholdMs));\n url.searchParams.set(\"timestamp\", new Date().toISOString());\n fireBeacon(url.toString());\n },\n });\n }, [ad, viewed, viewabilityThresholdMs]);\n\n const advertiser = ad.creative.advertiser_name ?? ad.creative.headline;\n\n return (\n <div ref={ref} className={className} style={inlineStyles.wrapper}>\n <span style={inlineStyles.badge} aria-label=\"Advertisement\">\n Ad\n </span>\n {advertiser ? (\n <span style={inlineStyles.advertiser}>{advertiser} </span>\n ) : null}\n <a\n href={ad.creative.destination_url}\n target=\"_blank\"\n rel=\"noopener sponsored\"\n style={inlineStyles.cta}\n >\n {ad.creative.cta_text}\n </a>\n </div>\n );\n}\n\nconst inlineStyles: Record<string, React.CSSProperties> = {\n // Block-level so the snippet starts on its own line below the text it\n // follows, but otherwise plain: no border, background, or padding.\n wrapper: {\n display: \"block\",\n margin: \"0.5rem 0\",\n fontSize: \"0.9em\",\n lineHeight: 1.5,\n },\n badge: {\n display: \"inline-block\",\n marginRight: \"0.4em\",\n padding: \"0.1em 0.4em\",\n borderRadius: 4,\n background: \"#30363d\",\n color: \"#8b949e\",\n fontSize: \"0.75em\",\n fontWeight: 700,\n letterSpacing: \"0.05em\",\n textTransform: \"uppercase\" as const,\n verticalAlign: \"middle\",\n },\n advertiser: {\n color: \"#8b949e\",\n },\n cta: {\n color: \"#58a6ff\",\n textDecoration: \"none\",\n fontWeight: 500,\n },\n};\n","import { useState, useEffect, useCallback } from \"react\";\nimport type { InlineAdEvent, InlineAdEventPayload } from \"@adzenai/core\";\n\n/** A run of message text, or an ad anchored to the end of the run before it. */\nexport type InlineAdSegment =\n | { kind: \"text\"; text: string }\n | { kind: \"ad\"; ad: InlineAdEventPayload };\n\nexport interface UseAdzenInlineAdsReturn {\n getInlineAdsForMessage(messageId: string): InlineAdEventPayload[];\n getInlineAdSegments(messageId: string, content: string): InlineAdSegment[];\n}\n\n/**\n * Ads without an anchor sort last so they render at the end of the message,\n * which is the best guess for a payload that predates `content_offset`.\n */\nfunction readOffset(payload: InlineAdEvent & { content_offset?: unknown }): number {\n return typeof payload.content_offset === \"number\"\n ? payload.content_offset\n : Number.MAX_SAFE_INTEGER;\n}\n\n/** A blank line, which ends a paragraph in both plain text and Markdown. */\nconst PARAGRAPH_BREAK = /\\n[ \\t]*\\n/;\nconst ENDS_ON_PARAGRAPH_BREAK = /\\n[ \\t]*\\n$/;\n\n/**\n * Moves an anchor forward to the end of the paragraph it falls in.\n *\n * Deltas are token-sized, so a raw offset routinely lands mid-word or inside\n * a Markdown construct (`**bold te|xt**`). Splitting there would break both\n * the sentence and the Markdown, so the ad is deferred to the next paragraph\n * break — the `paragraph_break` position the API asks for. While the paragraph\n * is still streaming there is no break yet, so the ad sits at the end of the\n * content and settles into place once the paragraph closes.\n */\nfunction snapToParagraphEnd(content: string, offset: number): number {\n if (offset >= content.length) return content.length;\n\n // The preceding frame already ended on a blank line, so this is the start of\n // a fresh paragraph and the ad belongs here.\n if (ENDS_ON_PARAGRAPH_BREAK.test(content.slice(0, offset))) return offset;\n\n // Search from one character back so an offset landing inside the blank line\n // itself still resolves to that break rather than skipping to the next one.\n return nextParagraphEnd(content, Math.max(0, offset - 1));\n}\n\n/**\n * Position just past the first paragraph break at or after `from`, or the end\n * of the content when no break follows.\n */\nfunction nextParagraphEnd(content: string, from: number): number {\n if (from >= content.length) return content.length;\n const match = PARAGRAPH_BREAK.exec(content.slice(from));\n return match ? from + match.index + match[0].length : content.length;\n}\n\n/**\n * Splits `content` into text and ad segments, placing each ad after the text\n * that had streamed when it arrived.\n *\n * At most one ad is placed per paragraph break. Several ads routinely resolve\n * to the same break — the API can emit a burst of them, and every ad anchored\n * inside one paragraph snaps to that paragraph's end — so each ad after the\n * first is moved to the next free break, with the end of the content usable as\n * a final slot. An ad with no free slot is left out and appears once the\n * message has grown enough to hold it, which keeps ads from piling up in one\n * spot while a paragraph is still streaming.\n *\n * @param ads Must be sorted by `content_offset` ascending.\n */\nexport function buildInlineAdSegments(\n content: string,\n ads: InlineAdEventPayload[],\n): InlineAdSegment[] {\n if (ads.length === 0) {\n return content ? [{ kind: \"text\", text: content }] : [];\n }\n\n const segments: InlineAdSegment[] = [];\n let cursor = 0;\n let lastAnchor = -1;\n\n for (const ad of ads) {\n let anchor = snapToParagraphEnd(content, Math.max(ad.content_offset, 0));\n if (anchor <= lastAnchor) anchor = nextParagraphEnd(content, lastAnchor);\n if (anchor <= lastAnchor) continue;\n\n if (anchor > cursor) {\n segments.push({ kind: \"text\", text: content.slice(cursor, anchor) });\n }\n segments.push({ kind: \"ad\", ad });\n cursor = anchor;\n lastAnchor = anchor;\n }\n\n if (cursor < content.length) {\n segments.push({ kind: \"text\", text: content.slice(cursor) });\n }\n\n return segments;\n}\n\n/**\n * React hook that subscribes to `adzen_inline_ad` custom events on\n * `window` and maintains a map of messageId -> InlineAdEventPayload[].\n *\n * Supports multiple inline ads per message per the cardinality requirements.\n * Ads are kept sorted by `content_offset` so they can be interleaved with the\n * message text at the point in the stream where they arrived.\n */\nexport function useAdzenInlineAds(): UseAdzenInlineAdsReturn {\n const [adsMap, setAdsMap] = useState<Map<string, InlineAdEventPayload[]>>(\n () => new Map(),\n );\n\n useEffect(() => {\n function handler(e: Event) {\n const detail = (e as CustomEvent).detail;\n if (!detail || typeof detail !== \"object\") return;\n\n const payload = detail as InlineAdEvent & { message_id?: string };\n const messageId = payload.message_id;\n if (!messageId) return;\n\n const anchored: InlineAdEventPayload = {\n ...payload,\n message_id: messageId,\n content_offset: readOffset(payload),\n };\n\n setAdsMap((prev) => {\n const existing = prev.get(messageId) ?? [];\n if (existing.some((a) => a.ad_id === anchored.ad_id)) return prev;\n const next = new Map(prev);\n next.set(\n messageId,\n [...existing, anchored].sort(\n (a, b) => a.content_offset - b.content_offset,\n ),\n );\n return next;\n });\n }\n\n window.addEventListener(\"adzen_inline_ad\", handler);\n return () => window.removeEventListener(\"adzen_inline_ad\", handler);\n }, []);\n\n const getInlineAdsForMessage = useCallback(\n (messageId: string): InlineAdEventPayload[] => {\n return adsMap.get(messageId) ?? [];\n },\n [adsMap],\n );\n\n const getInlineAdSegments = useCallback(\n (messageId: string, content: string): InlineAdSegment[] =>\n buildInlineAdSegments(content, adsMap.get(messageId) ?? []),\n [adsMap],\n );\n\n return { getInlineAdsForMessage, getInlineAdSegments };\n}\n","import type { AdzenPlacement, InlineAdEventPayload } from \"@adzenai/core\";\n\nfunction isCustomEvent(event: Record<string, unknown>): boolean {\n const type = String(event.type ?? \"\");\n return type === \"CUSTOM_EVENT\" || type === \"CUSTOM\" || type === \"CustomEvent\";\n}\n\n/**\n * Checks whether an AG-UI event is an `adzen_placement` custom event\n * and, if so, dispatches it as a browser `CustomEvent` on `window`\n * so that `useAdzenPlacement` can pick it up.\n *\n * Call this for every event returned by middleware `processEvent()` or\n * `processStream()`. Non-placement events are silently ignored.\n */\nexport function dispatchPlacementEvent(\n event: Record<string, unknown>,\n): boolean {\n if (typeof window === \"undefined\") return false;\n if (event.name !== \"adzen_placement\") return false;\n if (!isCustomEvent(event)) return false;\n\n const value = event.value as (AdzenPlacement & { message_id?: string }) | undefined;\n if (!value) return false;\n\n window.dispatchEvent(\n new CustomEvent(\"adzen_placement\", { detail: value }),\n );\n return true;\n}\n\n/**\n * Checks whether an AG-UI event is an `adzen_inline_ad` custom event\n * and, if so, dispatches it as a browser `CustomEvent` on `window`\n * so that `useAdzenInlineAds` can pick it up.\n */\nexport function dispatchInlineAdEvent(\n event: Record<string, unknown>,\n): boolean {\n if (typeof window === \"undefined\") return false;\n if (event.name !== \"adzen_inline_ad\") return false;\n if (!isCustomEvent(event)) return false;\n\n const value = event.value as Partial<InlineAdEventPayload> | undefined;\n if (!value) return false;\n\n window.dispatchEvent(\n new CustomEvent(\"adzen_inline_ad\", { detail: value }),\n );\n return true;\n}\n\n/**\n * Convenience wrapper: iterates an array of AG-UI events and dispatches\n * any placement or inline ad events to the browser.\n */\nexport function dispatchPlacementEvents(\n events: Record<string, unknown>[],\n): void {\n for (const event of events) {\n dispatchPlacementEvent(event);\n dispatchInlineAdEvent(event);\n }\n}\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect","useRef","useEffect","useState","observeViewability","jsx","jsxs","fireBeacon","useState","useEffect","useCallback"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type {\n AdzenPlacement,\n AdzenDecision,\n TrackingInfo,\n AdzenBaseConfig,\n} from \"@adzenai/core\";\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type {\n AdzenPlacement,\n ProcessResponse,\n ProcessResponseAd,\n AdzenBaseConfig,\n InlineAdEvent,\n InlineAdEventPayload,\n InlineAdCreative,\n PlacementRecord,\n PlacementsResponse,\n AdzenStreamStartEvent,\n AdzenStreamEndEvent,\n AdzenStreamErrorEvent,\n AdzenStreamEvent,\n} from \"@adzenai/core\";\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
package/dist/index.d.cts CHANGED
@@ -1 +1 @@
1
- export { AdzenBaseConfig, AdzenDecision, AdzenPlacement, TrackingInfo } from '@adzenai/core';
1
+ export { AdzenBaseConfig, AdzenPlacement, AdzenStreamEndEvent, AdzenStreamErrorEvent, AdzenStreamEvent, AdzenStreamStartEvent, InlineAdCreative, InlineAdEvent, InlineAdEventPayload, PlacementRecord, PlacementsResponse, ProcessResponse, ProcessResponseAd } from '@adzenai/core';
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { AdzenBaseConfig, AdzenDecision, AdzenPlacement, TrackingInfo } from '@adzenai/core';
1
+ export { AdzenBaseConfig, AdzenPlacement, AdzenStreamEndEvent, AdzenStreamErrorEvent, AdzenStreamEvent, AdzenStreamStartEvent, InlineAdCreative, InlineAdEvent, InlineAdEventPayload, PlacementRecord, PlacementsResponse, ProcessResponse, ProcessResponseAd } from '@adzenai/core';