@adzenai/ai 0.0.1

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.
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/copilotkit/index.ts
21
+ var copilotkit_exports = {};
22
+ __export(copilotkit_exports, {
23
+ AdzenAsyncMiddleware: () => AdzenAsyncMiddleware
24
+ });
25
+ module.exports = __toCommonJS(copilotkit_exports);
26
+
27
+ // src/copilotkit/middleware.ts
28
+ function isFinalOutputEvent(event) {
29
+ const type = String(event.type ?? "");
30
+ if (type === "RUN_FINISHED" || type === "RunFinished") return false;
31
+ if (type !== "CUSTOM" && type !== "CUSTOM_EVENT" && type !== "CustomEvent")
32
+ return false;
33
+ if (event.final === true || event.isFinal === true) return true;
34
+ const name = String(event.name ?? event.event ?? "").toLowerCase();
35
+ return name.includes("assistant_final") || name.includes("final_output");
36
+ }
37
+ function extractContentFromEvent(event) {
38
+ for (const key of ["output", "result", "data", "payload", "message"]) {
39
+ const val = event[key];
40
+ if (typeof val === "string" && val.length > 0) return val;
41
+ if (typeof val === "object" && val !== null) {
42
+ try {
43
+ return JSON.stringify(val);
44
+ } catch {
45
+ continue;
46
+ }
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ var AdzenAsyncMiddleware = class {
52
+ config;
53
+ buffers = /* @__PURE__ */ new Map();
54
+ fetchedIds = /* @__PURE__ */ new Set();
55
+ pendingFetches = [];
56
+ fallbackCounter = 0;
57
+ constructor(config) {
58
+ this.config = {
59
+ ...config,
60
+ endpointUrl: config.endpointUrl ?? "https://api.adzen.ai/v1/ai",
61
+ timeoutMs: config.timeoutMs ?? 3e3,
62
+ adUnitPosition: config.adUnitPosition ?? "chin"
63
+ };
64
+ }
65
+ /**
66
+ * Process a single AG-UI event. Returns an array of events to emit
67
+ * downstream (always includes the original event, possibly followed
68
+ * by an `adzen_placement` custom event).
69
+ */
70
+ async processEvent(event) {
71
+ const type = String(event.type ?? "");
72
+ switch (type) {
73
+ case "TEXT_MESSAGE_START":
74
+ case "TextMessageStart": {
75
+ const messageId = this.resolveMessageId(event);
76
+ this.evictStaleBuffers();
77
+ this.buffers.set(messageId, {
78
+ content: "",
79
+ startedAt: Date.now(),
80
+ fetched: false
81
+ });
82
+ return [event];
83
+ }
84
+ case "TEXT_MESSAGE_CONTENT":
85
+ case "TextMessageContent": {
86
+ const messageId = String(event.messageId ?? "");
87
+ const buf = this.buffers.get(messageId);
88
+ if (buf) buf.content += String(event.delta ?? "");
89
+ return [event];
90
+ }
91
+ case "TEXT_MESSAGE_END":
92
+ case "TextMessageEnd": {
93
+ const messageId = String(event.messageId ?? "");
94
+ const buf = this.buffers.get(messageId);
95
+ const out = [event];
96
+ if (buf && !buf.fetched) {
97
+ buf.fetched = true;
98
+ this.fetchedIds.add(messageId);
99
+ const fetchPromise = this.fetchAd(buf.content, messageId).then(
100
+ (placement) => {
101
+ if (placement) out.push(this.makePlacementEvent(placement, messageId));
102
+ }
103
+ );
104
+ this.pendingFetches.push(fetchPromise);
105
+ await fetchPromise;
106
+ this.buffers.delete(messageId);
107
+ }
108
+ return out;
109
+ }
110
+ case "CUSTOM":
111
+ case "CUSTOM_EVENT":
112
+ case "CustomEvent": {
113
+ if (isFinalOutputEvent(event)) {
114
+ const messageId = String(event.messageId ?? "");
115
+ if (!this.fetchedIds.has(messageId)) {
116
+ const buf = this.buffers.get(messageId);
117
+ const content = extractContentFromEvent(event);
118
+ if (content) {
119
+ const out = [event];
120
+ if (buf) buf.fetched = true;
121
+ this.fetchedIds.add(messageId);
122
+ const fetchPromise = this.fetchAd(content, messageId).then(
123
+ (placement) => {
124
+ if (placement) out.push(this.makePlacementEvent(placement, messageId));
125
+ }
126
+ );
127
+ this.pendingFetches.push(fetchPromise);
128
+ await fetchPromise;
129
+ return out;
130
+ }
131
+ }
132
+ }
133
+ return [event];
134
+ }
135
+ case "RUN_FINISHED":
136
+ case "RunFinished": {
137
+ await Promise.allSettled(this.pendingFetches);
138
+ this.pendingFetches = [];
139
+ return [event];
140
+ }
141
+ default:
142
+ return [event];
143
+ }
144
+ }
145
+ resolveMessageId(event) {
146
+ const id = String(event.messageId ?? "");
147
+ if (id) return id;
148
+ return `__adzen_fallback_${Date.now()}_${this.fallbackCounter++}`;
149
+ }
150
+ evictStaleBuffers() {
151
+ const cutoff = Date.now() - this.config.timeoutMs * 2;
152
+ for (const [key, buf] of this.buffers) {
153
+ if (buf.startedAt < cutoff) this.buffers.delete(key);
154
+ }
155
+ }
156
+ async fetchAd(content, messageId) {
157
+ const controller = new AbortController();
158
+ const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
159
+ try {
160
+ const res = await fetch(`${this.config.endpointUrl}/process`, {
161
+ method: "POST",
162
+ headers: {
163
+ "Content-Type": "application/json",
164
+ "X-API-Key": this.config.apiKey
165
+ },
166
+ body: JSON.stringify({
167
+ content,
168
+ message_id: messageId
169
+ }),
170
+ signal: controller.signal
171
+ });
172
+ if (!res.ok) return null;
173
+ const data = await res.json();
174
+ if (data.decision === "serve" && data.ad) return data.ad;
175
+ return null;
176
+ } catch {
177
+ return null;
178
+ } finally {
179
+ clearTimeout(timeout);
180
+ }
181
+ }
182
+ makePlacementEvent(placement, messageId) {
183
+ return {
184
+ type: "CUSTOM_EVENT",
185
+ name: "adzen_placement",
186
+ messageId,
187
+ value: {
188
+ ...placement,
189
+ message_id: messageId
190
+ }
191
+ };
192
+ }
193
+ };
194
+ // Annotate the CommonJS export names for ESM import in node:
195
+ 0 && (module.exports = {
196
+ AdzenAsyncMiddleware
197
+ });
198
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/copilotkit/index.ts","../../src/copilotkit/middleware.ts"],"sourcesContent":["export { AdzenAsyncMiddleware } from \"./middleware.js\";\nexport type { AdzenAsyncConfig } from \"./middleware.js\";\n","import type { AdzenDecision, AdzenPlacement } from \"@adzenai/core\";\n\nexport interface AdzenAsyncConfig {\n endpointUrl?: string;\n apiKey: string;\n timeoutMs?: number;\n adUnitPosition?: string;\n}\n\ninterface MessageBuffer {\n content: string;\n startedAt: number;\n fetched: boolean;\n}\n\nfunction isFinalOutputEvent(event: Record<string, unknown>): boolean {\n const type = String(event.type ?? \"\");\n if (type === \"RUN_FINISHED\" || type === \"RunFinished\") return false;\n if (type !== \"CUSTOM\" && type !== \"CUSTOM_EVENT\" && type !== \"CustomEvent\")\n return false;\n if (event.final === true || event.isFinal === true) return true;\n const name = String(event.name ?? event.event ?? \"\").toLowerCase();\n return name.includes(\"assistant_final\") || name.includes(\"final_output\");\n}\n\nfunction extractContentFromEvent(event: Record<string, unknown>): string | null {\n for (const key of [\"output\", \"result\", \"data\", \"payload\", \"message\"]) {\n const val = event[key];\n if (typeof val === \"string\" && val.length > 0) return val;\n if (typeof val === \"object\" && val !== null) {\n try {\n return JSON.stringify(val);\n } catch {\n continue;\n }\n }\n }\n return null;\n}\n\n/**\n * AG-UI middleware that intercepts the event stream and calls AI-API after\n * each assistant message, emitting `adzen_placement` custom events when an\n * ad is returned.\n *\n * All upstream events pass through immediately — zero latency is added to\n * the text stream. Ad fetches run as a side-effect and `RUN_FINISHED` is\n * held until all pending fetches settle.\n */\nexport class AdzenAsyncMiddleware {\n private config: Required<Pick<AdzenAsyncConfig, \"endpointUrl\" | \"timeoutMs\" | \"adUnitPosition\">> &\n AdzenAsyncConfig;\n private buffers = new Map<string, MessageBuffer>();\n private fetchedIds = new Set<string>();\n private pendingFetches: Promise<void>[] = [];\n private fallbackCounter = 0;\n\n constructor(config: AdzenAsyncConfig) {\n this.config = {\n ...config,\n endpointUrl: config.endpointUrl ?? \"https://api.adzen.ai/v1/ai\",\n timeoutMs: config.timeoutMs ?? 3000,\n adUnitPosition: config.adUnitPosition ?? \"chin\",\n };\n }\n\n /**\n * Process a single AG-UI event. Returns an array of events to emit\n * downstream (always includes the original event, possibly followed\n * by an `adzen_placement` custom event).\n */\n async processEvent(event: Record<string, unknown>): Promise<Record<string, unknown>[]> {\n const type = String(event.type ?? \"\");\n\n switch (type) {\n case \"TEXT_MESSAGE_START\":\n case \"TextMessageStart\": {\n const messageId = this.resolveMessageId(event);\n this.evictStaleBuffers();\n this.buffers.set(messageId, {\n content: \"\",\n startedAt: Date.now(),\n fetched: false,\n });\n return [event];\n }\n\n case \"TEXT_MESSAGE_CONTENT\":\n case \"TextMessageContent\": {\n const messageId = String(event.messageId ?? \"\");\n const buf = this.buffers.get(messageId);\n if (buf) buf.content += String(event.delta ?? \"\");\n return [event];\n }\n\n case \"TEXT_MESSAGE_END\":\n case \"TextMessageEnd\": {\n const messageId = String(event.messageId ?? \"\");\n const buf = this.buffers.get(messageId);\n const out: Record<string, unknown>[] = [event];\n\n if (buf && !buf.fetched) {\n buf.fetched = true;\n this.fetchedIds.add(messageId);\n const fetchPromise = this.fetchAd(buf.content, messageId).then(\n (placement) => {\n if (placement) out.push(this.makePlacementEvent(placement, messageId));\n },\n );\n this.pendingFetches.push(fetchPromise);\n await fetchPromise;\n this.buffers.delete(messageId);\n }\n\n return out;\n }\n\n case \"CUSTOM\":\n case \"CUSTOM_EVENT\":\n case \"CustomEvent\": {\n if (isFinalOutputEvent(event)) {\n const messageId = String(event.messageId ?? \"\");\n if (!this.fetchedIds.has(messageId)) {\n const buf = this.buffers.get(messageId);\n const content = extractContentFromEvent(event);\n if (content) {\n const out: Record<string, unknown>[] = [event];\n if (buf) buf.fetched = true;\n this.fetchedIds.add(messageId);\n const fetchPromise = this.fetchAd(content, messageId).then(\n (placement) => {\n if (placement) out.push(this.makePlacementEvent(placement, messageId));\n },\n );\n this.pendingFetches.push(fetchPromise);\n await fetchPromise;\n return out;\n }\n }\n }\n return [event];\n }\n\n case \"RUN_FINISHED\":\n case \"RunFinished\": {\n await Promise.allSettled(this.pendingFetches);\n this.pendingFetches = [];\n return [event];\n }\n\n default:\n return [event];\n }\n }\n\n private resolveMessageId(event: Record<string, unknown>): string {\n const id = String(event.messageId ?? \"\");\n if (id) return id;\n return `__adzen_fallback_${Date.now()}_${this.fallbackCounter++}`;\n }\n\n private evictStaleBuffers(): void {\n const cutoff = Date.now() - this.config.timeoutMs * 2;\n for (const [key, buf] of this.buffers) {\n if (buf.startedAt < cutoff) this.buffers.delete(key);\n }\n }\n\n private async fetchAd(\n content: string,\n messageId: string,\n ): Promise<AdzenPlacement | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);\n\n try {\n const res = await fetch(`${this.config.endpointUrl}/process`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.config.apiKey,\n },\n body: JSON.stringify({\n content,\n message_id: messageId,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as AdzenDecision;\n if (data.decision === \"serve\" && data.ad) return data.ad;\n return null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private makePlacementEvent(\n placement: AdzenPlacement,\n messageId: string,\n ): Record<string, unknown> {\n return {\n type: \"CUSTOM_EVENT\",\n name: \"adzen_placement\",\n messageId,\n value: {\n ...placement,\n message_id: messageId,\n },\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACeA,SAAS,mBAAmB,OAAyC;AACnE,QAAM,OAAO,OAAO,MAAM,QAAQ,EAAE;AACpC,MAAI,SAAS,kBAAkB,SAAS,cAAe,QAAO;AAC9D,MAAI,SAAS,YAAY,SAAS,kBAAkB,SAAS;AAC3D,WAAO;AACT,MAAI,MAAM,UAAU,QAAQ,MAAM,YAAY,KAAM,QAAO;AAC3D,QAAM,OAAO,OAAO,MAAM,QAAQ,MAAM,SAAS,EAAE,EAAE,YAAY;AACjE,SAAO,KAAK,SAAS,iBAAiB,KAAK,KAAK,SAAS,cAAc;AACzE;AAEA,SAAS,wBAAwB,OAA+C;AAC9E,aAAW,OAAO,CAAC,UAAU,UAAU,QAAQ,WAAW,SAAS,GAAG;AACpE,UAAM,MAAM,MAAM,GAAG;AACrB,QAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,EAAG,QAAO;AACtD,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAI;AACF,eAAO,KAAK,UAAU,GAAG;AAAA,MAC3B,QAAQ;AACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAWO,IAAM,uBAAN,MAA2B;AAAA,EACxB;AAAA,EAEA,UAAU,oBAAI,IAA2B;AAAA,EACzC,aAAa,oBAAI,IAAY;AAAA,EAC7B,iBAAkC,CAAC;AAAA,EACnC,kBAAkB;AAAA,EAE1B,YAAY,QAA0B;AACpC,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,aAAa,OAAO,eAAe;AAAA,MACnC,WAAW,OAAO,aAAa;AAAA,MAC/B,gBAAgB,OAAO,kBAAkB;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,OAAoE;AACrF,UAAM,OAAO,OAAO,MAAM,QAAQ,EAAE;AAEpC,YAAQ,MAAM;AAAA,MACZ,KAAK;AAAA,MACL,KAAK,oBAAoB;AACvB,cAAM,YAAY,KAAK,iBAAiB,KAAK;AAC7C,aAAK,kBAAkB;AACvB,aAAK,QAAQ,IAAI,WAAW;AAAA,UAC1B,SAAS;AAAA,UACT,WAAW,KAAK,IAAI;AAAA,UACpB,SAAS;AAAA,QACX,CAAC;AACD,eAAO,CAAC,KAAK;AAAA,MACf;AAAA,MAEA,KAAK;AAAA,MACL,KAAK,sBAAsB;AACzB,cAAM,YAAY,OAAO,MAAM,aAAa,EAAE;AAC9C,cAAM,MAAM,KAAK,QAAQ,IAAI,SAAS;AACtC,YAAI,IAAK,KAAI,WAAW,OAAO,MAAM,SAAS,EAAE;AAChD,eAAO,CAAC,KAAK;AAAA,MACf;AAAA,MAEA,KAAK;AAAA,MACL,KAAK,kBAAkB;AACrB,cAAM,YAAY,OAAO,MAAM,aAAa,EAAE;AAC9C,cAAM,MAAM,KAAK,QAAQ,IAAI,SAAS;AACtC,cAAM,MAAiC,CAAC,KAAK;AAE7C,YAAI,OAAO,CAAC,IAAI,SAAS;AACvB,cAAI,UAAU;AACd,eAAK,WAAW,IAAI,SAAS;AAC7B,gBAAM,eAAe,KAAK,QAAQ,IAAI,SAAS,SAAS,EAAE;AAAA,YACxD,CAAC,cAAc;AACb,kBAAI,UAAW,KAAI,KAAK,KAAK,mBAAmB,WAAW,SAAS,CAAC;AAAA,YACvE;AAAA,UACF;AACA,eAAK,eAAe,KAAK,YAAY;AACrC,gBAAM;AACN,eAAK,QAAQ,OAAO,SAAS;AAAA,QAC/B;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,eAAe;AAClB,YAAI,mBAAmB,KAAK,GAAG;AAC7B,gBAAM,YAAY,OAAO,MAAM,aAAa,EAAE;AAC9C,cAAI,CAAC,KAAK,WAAW,IAAI,SAAS,GAAG;AACnC,kBAAM,MAAM,KAAK,QAAQ,IAAI,SAAS;AACtC,kBAAM,UAAU,wBAAwB,KAAK;AAC7C,gBAAI,SAAS;AACX,oBAAM,MAAiC,CAAC,KAAK;AAC7C,kBAAI,IAAK,KAAI,UAAU;AACvB,mBAAK,WAAW,IAAI,SAAS;AAC7B,oBAAM,eAAe,KAAK,QAAQ,SAAS,SAAS,EAAE;AAAA,gBACpD,CAAC,cAAc;AACb,sBAAI,UAAW,KAAI,KAAK,KAAK,mBAAmB,WAAW,SAAS,CAAC;AAAA,gBACvE;AAAA,cACF;AACA,mBAAK,eAAe,KAAK,YAAY;AACrC,oBAAM;AACN,qBAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF;AACA,eAAO,CAAC,KAAK;AAAA,MACf;AAAA,MAEA,KAAK;AAAA,MACL,KAAK,eAAe;AAClB,cAAM,QAAQ,WAAW,KAAK,cAAc;AAC5C,aAAK,iBAAiB,CAAC;AACvB,eAAO,CAAC,KAAK;AAAA,MACf;AAAA,MAEA;AACE,eAAO,CAAC,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEQ,iBAAiB,OAAwC;AAC/D,UAAM,KAAK,OAAO,MAAM,aAAa,EAAE;AACvC,QAAI,GAAI,QAAO;AACf,WAAO,oBAAoB,KAAK,IAAI,CAAC,IAAI,KAAK,iBAAiB;AAAA,EACjE;AAAA,EAEQ,oBAA0B;AAChC,UAAM,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO,YAAY;AACpD,eAAW,CAAC,KAAK,GAAG,KAAK,KAAK,SAAS;AACrC,UAAI,IAAI,YAAY,OAAQ,MAAK,QAAQ,OAAO,GAAG;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAc,QACZ,SACA,WACgC;AAChC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO,SAAS;AAE1E,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,YAAY;AAAA,QAC5D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,KAAK,OAAO;AAAA,QAC3B;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,YAAY;AAAA,QACd,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAED,UAAI,CAAC,IAAI,GAAI,QAAO;AAEpB,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAI,KAAK,aAAa,WAAW,KAAK,GAAI,QAAO,KAAK;AACtD,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEQ,mBACN,WACA,WACyB;AACzB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,35 @@
1
+ interface AdzenAsyncConfig {
2
+ endpointUrl?: string;
3
+ apiKey: string;
4
+ timeoutMs?: number;
5
+ adUnitPosition?: string;
6
+ }
7
+ /**
8
+ * AG-UI middleware that intercepts the event stream and calls AI-API after
9
+ * each assistant message, emitting `adzen_placement` custom events when an
10
+ * ad is returned.
11
+ *
12
+ * All upstream events pass through immediately — zero latency is added to
13
+ * the text stream. Ad fetches run as a side-effect and `RUN_FINISHED` is
14
+ * held until all pending fetches settle.
15
+ */
16
+ declare class AdzenAsyncMiddleware {
17
+ private config;
18
+ private buffers;
19
+ private fetchedIds;
20
+ private pendingFetches;
21
+ private fallbackCounter;
22
+ constructor(config: AdzenAsyncConfig);
23
+ /**
24
+ * Process a single AG-UI event. Returns an array of events to emit
25
+ * downstream (always includes the original event, possibly followed
26
+ * by an `adzen_placement` custom event).
27
+ */
28
+ processEvent(event: Record<string, unknown>): Promise<Record<string, unknown>[]>;
29
+ private resolveMessageId;
30
+ private evictStaleBuffers;
31
+ private fetchAd;
32
+ private makePlacementEvent;
33
+ }
34
+
35
+ export { type AdzenAsyncConfig, AdzenAsyncMiddleware };
@@ -0,0 +1,35 @@
1
+ interface AdzenAsyncConfig {
2
+ endpointUrl?: string;
3
+ apiKey: string;
4
+ timeoutMs?: number;
5
+ adUnitPosition?: string;
6
+ }
7
+ /**
8
+ * AG-UI middleware that intercepts the event stream and calls AI-API after
9
+ * each assistant message, emitting `adzen_placement` custom events when an
10
+ * ad is returned.
11
+ *
12
+ * All upstream events pass through immediately — zero latency is added to
13
+ * the text stream. Ad fetches run as a side-effect and `RUN_FINISHED` is
14
+ * held until all pending fetches settle.
15
+ */
16
+ declare class AdzenAsyncMiddleware {
17
+ private config;
18
+ private buffers;
19
+ private fetchedIds;
20
+ private pendingFetches;
21
+ private fallbackCounter;
22
+ constructor(config: AdzenAsyncConfig);
23
+ /**
24
+ * Process a single AG-UI event. Returns an array of events to emit
25
+ * downstream (always includes the original event, possibly followed
26
+ * by an `adzen_placement` custom event).
27
+ */
28
+ processEvent(event: Record<string, unknown>): Promise<Record<string, unknown>[]>;
29
+ private resolveMessageId;
30
+ private evictStaleBuffers;
31
+ private fetchAd;
32
+ private makePlacementEvent;
33
+ }
34
+
35
+ export { type AdzenAsyncConfig, AdzenAsyncMiddleware };
@@ -0,0 +1,171 @@
1
+ // src/copilotkit/middleware.ts
2
+ function isFinalOutputEvent(event) {
3
+ const type = String(event.type ?? "");
4
+ if (type === "RUN_FINISHED" || type === "RunFinished") return false;
5
+ if (type !== "CUSTOM" && type !== "CUSTOM_EVENT" && type !== "CustomEvent")
6
+ return false;
7
+ if (event.final === true || event.isFinal === true) return true;
8
+ const name = String(event.name ?? event.event ?? "").toLowerCase();
9
+ return name.includes("assistant_final") || name.includes("final_output");
10
+ }
11
+ function extractContentFromEvent(event) {
12
+ for (const key of ["output", "result", "data", "payload", "message"]) {
13
+ const val = event[key];
14
+ if (typeof val === "string" && val.length > 0) return val;
15
+ if (typeof val === "object" && val !== null) {
16
+ try {
17
+ return JSON.stringify(val);
18
+ } catch {
19
+ continue;
20
+ }
21
+ }
22
+ }
23
+ return null;
24
+ }
25
+ var AdzenAsyncMiddleware = class {
26
+ config;
27
+ buffers = /* @__PURE__ */ new Map();
28
+ fetchedIds = /* @__PURE__ */ new Set();
29
+ pendingFetches = [];
30
+ fallbackCounter = 0;
31
+ constructor(config) {
32
+ this.config = {
33
+ ...config,
34
+ endpointUrl: config.endpointUrl ?? "https://api.adzen.ai/v1/ai",
35
+ timeoutMs: config.timeoutMs ?? 3e3,
36
+ adUnitPosition: config.adUnitPosition ?? "chin"
37
+ };
38
+ }
39
+ /**
40
+ * Process a single AG-UI event. Returns an array of events to emit
41
+ * downstream (always includes the original event, possibly followed
42
+ * by an `adzen_placement` custom event).
43
+ */
44
+ async processEvent(event) {
45
+ const type = String(event.type ?? "");
46
+ switch (type) {
47
+ case "TEXT_MESSAGE_START":
48
+ case "TextMessageStart": {
49
+ const messageId = this.resolveMessageId(event);
50
+ this.evictStaleBuffers();
51
+ this.buffers.set(messageId, {
52
+ content: "",
53
+ startedAt: Date.now(),
54
+ fetched: false
55
+ });
56
+ return [event];
57
+ }
58
+ case "TEXT_MESSAGE_CONTENT":
59
+ case "TextMessageContent": {
60
+ const messageId = String(event.messageId ?? "");
61
+ const buf = this.buffers.get(messageId);
62
+ if (buf) buf.content += String(event.delta ?? "");
63
+ return [event];
64
+ }
65
+ case "TEXT_MESSAGE_END":
66
+ case "TextMessageEnd": {
67
+ const messageId = String(event.messageId ?? "");
68
+ const buf = this.buffers.get(messageId);
69
+ const out = [event];
70
+ if (buf && !buf.fetched) {
71
+ buf.fetched = true;
72
+ this.fetchedIds.add(messageId);
73
+ const fetchPromise = this.fetchAd(buf.content, messageId).then(
74
+ (placement) => {
75
+ if (placement) out.push(this.makePlacementEvent(placement, messageId));
76
+ }
77
+ );
78
+ this.pendingFetches.push(fetchPromise);
79
+ await fetchPromise;
80
+ this.buffers.delete(messageId);
81
+ }
82
+ return out;
83
+ }
84
+ case "CUSTOM":
85
+ case "CUSTOM_EVENT":
86
+ case "CustomEvent": {
87
+ if (isFinalOutputEvent(event)) {
88
+ const messageId = String(event.messageId ?? "");
89
+ if (!this.fetchedIds.has(messageId)) {
90
+ const buf = this.buffers.get(messageId);
91
+ const content = extractContentFromEvent(event);
92
+ if (content) {
93
+ const out = [event];
94
+ if (buf) buf.fetched = true;
95
+ this.fetchedIds.add(messageId);
96
+ const fetchPromise = this.fetchAd(content, messageId).then(
97
+ (placement) => {
98
+ if (placement) out.push(this.makePlacementEvent(placement, messageId));
99
+ }
100
+ );
101
+ this.pendingFetches.push(fetchPromise);
102
+ await fetchPromise;
103
+ return out;
104
+ }
105
+ }
106
+ }
107
+ return [event];
108
+ }
109
+ case "RUN_FINISHED":
110
+ case "RunFinished": {
111
+ await Promise.allSettled(this.pendingFetches);
112
+ this.pendingFetches = [];
113
+ return [event];
114
+ }
115
+ default:
116
+ return [event];
117
+ }
118
+ }
119
+ resolveMessageId(event) {
120
+ const id = String(event.messageId ?? "");
121
+ if (id) return id;
122
+ return `__adzen_fallback_${Date.now()}_${this.fallbackCounter++}`;
123
+ }
124
+ evictStaleBuffers() {
125
+ const cutoff = Date.now() - this.config.timeoutMs * 2;
126
+ for (const [key, buf] of this.buffers) {
127
+ if (buf.startedAt < cutoff) this.buffers.delete(key);
128
+ }
129
+ }
130
+ async fetchAd(content, messageId) {
131
+ const controller = new AbortController();
132
+ const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);
133
+ try {
134
+ const res = await fetch(`${this.config.endpointUrl}/process`, {
135
+ method: "POST",
136
+ headers: {
137
+ "Content-Type": "application/json",
138
+ "X-API-Key": this.config.apiKey
139
+ },
140
+ body: JSON.stringify({
141
+ content,
142
+ message_id: messageId
143
+ }),
144
+ signal: controller.signal
145
+ });
146
+ if (!res.ok) return null;
147
+ const data = await res.json();
148
+ if (data.decision === "serve" && data.ad) return data.ad;
149
+ return null;
150
+ } catch {
151
+ return null;
152
+ } finally {
153
+ clearTimeout(timeout);
154
+ }
155
+ }
156
+ makePlacementEvent(placement, messageId) {
157
+ return {
158
+ type: "CUSTOM_EVENT",
159
+ name: "adzen_placement",
160
+ messageId,
161
+ value: {
162
+ ...placement,
163
+ message_id: messageId
164
+ }
165
+ };
166
+ }
167
+ };
168
+ export {
169
+ AdzenAsyncMiddleware
170
+ };
171
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/copilotkit/middleware.ts"],"sourcesContent":["import type { AdzenDecision, AdzenPlacement } from \"@adzenai/core\";\n\nexport interface AdzenAsyncConfig {\n endpointUrl?: string;\n apiKey: string;\n timeoutMs?: number;\n adUnitPosition?: string;\n}\n\ninterface MessageBuffer {\n content: string;\n startedAt: number;\n fetched: boolean;\n}\n\nfunction isFinalOutputEvent(event: Record<string, unknown>): boolean {\n const type = String(event.type ?? \"\");\n if (type === \"RUN_FINISHED\" || type === \"RunFinished\") return false;\n if (type !== \"CUSTOM\" && type !== \"CUSTOM_EVENT\" && type !== \"CustomEvent\")\n return false;\n if (event.final === true || event.isFinal === true) return true;\n const name = String(event.name ?? event.event ?? \"\").toLowerCase();\n return name.includes(\"assistant_final\") || name.includes(\"final_output\");\n}\n\nfunction extractContentFromEvent(event: Record<string, unknown>): string | null {\n for (const key of [\"output\", \"result\", \"data\", \"payload\", \"message\"]) {\n const val = event[key];\n if (typeof val === \"string\" && val.length > 0) return val;\n if (typeof val === \"object\" && val !== null) {\n try {\n return JSON.stringify(val);\n } catch {\n continue;\n }\n }\n }\n return null;\n}\n\n/**\n * AG-UI middleware that intercepts the event stream and calls AI-API after\n * each assistant message, emitting `adzen_placement` custom events when an\n * ad is returned.\n *\n * All upstream events pass through immediately — zero latency is added to\n * the text stream. Ad fetches run as a side-effect and `RUN_FINISHED` is\n * held until all pending fetches settle.\n */\nexport class AdzenAsyncMiddleware {\n private config: Required<Pick<AdzenAsyncConfig, \"endpointUrl\" | \"timeoutMs\" | \"adUnitPosition\">> &\n AdzenAsyncConfig;\n private buffers = new Map<string, MessageBuffer>();\n private fetchedIds = new Set<string>();\n private pendingFetches: Promise<void>[] = [];\n private fallbackCounter = 0;\n\n constructor(config: AdzenAsyncConfig) {\n this.config = {\n ...config,\n endpointUrl: config.endpointUrl ?? \"https://api.adzen.ai/v1/ai\",\n timeoutMs: config.timeoutMs ?? 3000,\n adUnitPosition: config.adUnitPosition ?? \"chin\",\n };\n }\n\n /**\n * Process a single AG-UI event. Returns an array of events to emit\n * downstream (always includes the original event, possibly followed\n * by an `adzen_placement` custom event).\n */\n async processEvent(event: Record<string, unknown>): Promise<Record<string, unknown>[]> {\n const type = String(event.type ?? \"\");\n\n switch (type) {\n case \"TEXT_MESSAGE_START\":\n case \"TextMessageStart\": {\n const messageId = this.resolveMessageId(event);\n this.evictStaleBuffers();\n this.buffers.set(messageId, {\n content: \"\",\n startedAt: Date.now(),\n fetched: false,\n });\n return [event];\n }\n\n case \"TEXT_MESSAGE_CONTENT\":\n case \"TextMessageContent\": {\n const messageId = String(event.messageId ?? \"\");\n const buf = this.buffers.get(messageId);\n if (buf) buf.content += String(event.delta ?? \"\");\n return [event];\n }\n\n case \"TEXT_MESSAGE_END\":\n case \"TextMessageEnd\": {\n const messageId = String(event.messageId ?? \"\");\n const buf = this.buffers.get(messageId);\n const out: Record<string, unknown>[] = [event];\n\n if (buf && !buf.fetched) {\n buf.fetched = true;\n this.fetchedIds.add(messageId);\n const fetchPromise = this.fetchAd(buf.content, messageId).then(\n (placement) => {\n if (placement) out.push(this.makePlacementEvent(placement, messageId));\n },\n );\n this.pendingFetches.push(fetchPromise);\n await fetchPromise;\n this.buffers.delete(messageId);\n }\n\n return out;\n }\n\n case \"CUSTOM\":\n case \"CUSTOM_EVENT\":\n case \"CustomEvent\": {\n if (isFinalOutputEvent(event)) {\n const messageId = String(event.messageId ?? \"\");\n if (!this.fetchedIds.has(messageId)) {\n const buf = this.buffers.get(messageId);\n const content = extractContentFromEvent(event);\n if (content) {\n const out: Record<string, unknown>[] = [event];\n if (buf) buf.fetched = true;\n this.fetchedIds.add(messageId);\n const fetchPromise = this.fetchAd(content, messageId).then(\n (placement) => {\n if (placement) out.push(this.makePlacementEvent(placement, messageId));\n },\n );\n this.pendingFetches.push(fetchPromise);\n await fetchPromise;\n return out;\n }\n }\n }\n return [event];\n }\n\n case \"RUN_FINISHED\":\n case \"RunFinished\": {\n await Promise.allSettled(this.pendingFetches);\n this.pendingFetches = [];\n return [event];\n }\n\n default:\n return [event];\n }\n }\n\n private resolveMessageId(event: Record<string, unknown>): string {\n const id = String(event.messageId ?? \"\");\n if (id) return id;\n return `__adzen_fallback_${Date.now()}_${this.fallbackCounter++}`;\n }\n\n private evictStaleBuffers(): void {\n const cutoff = Date.now() - this.config.timeoutMs * 2;\n for (const [key, buf] of this.buffers) {\n if (buf.startedAt < cutoff) this.buffers.delete(key);\n }\n }\n\n private async fetchAd(\n content: string,\n messageId: string,\n ): Promise<AdzenPlacement | null> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs);\n\n try {\n const res = await fetch(`${this.config.endpointUrl}/process`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.config.apiKey,\n },\n body: JSON.stringify({\n content,\n message_id: messageId,\n }),\n signal: controller.signal,\n });\n\n if (!res.ok) return null;\n\n const data = (await res.json()) as AdzenDecision;\n if (data.decision === \"serve\" && data.ad) return data.ad;\n return null;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private makePlacementEvent(\n placement: AdzenPlacement,\n messageId: string,\n ): Record<string, unknown> {\n return {\n type: \"CUSTOM_EVENT\",\n name: \"adzen_placement\",\n messageId,\n value: {\n ...placement,\n message_id: messageId,\n },\n };\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/copilotkit/react/index.ts
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ AdzenCard: () => AdzenCard,
24
+ dispatchPlacementEvent: () => dispatchPlacementEvent,
25
+ dispatchPlacementEvents: () => dispatchPlacementEvents,
26
+ useAdzenPlacement: () => useAdzenPlacement
27
+ });
28
+ module.exports = __toCommonJS(react_exports);
29
+
30
+ // src/copilotkit/react/AdzenCard.tsx
31
+ var import_react2 = require("react");
32
+ var import_core = require("@adzenai/core");
33
+
34
+ // src/copilotkit/react/useAdzenPlacement.ts
35
+ var import_react = require("react");
36
+ function useAdzenPlacement() {
37
+ const [placements, setPlacements] = (0, import_react.useState)(
38
+ () => /* @__PURE__ */ new Map()
39
+ );
40
+ (0, import_react.useEffect)(() => {
41
+ function handler(e) {
42
+ const detail = e.detail;
43
+ if (!detail || typeof detail !== "object") return;
44
+ const placement = detail;
45
+ const messageId = placement.message_id;
46
+ if (!messageId) return;
47
+ setPlacements((prev) => {
48
+ const existing = prev.get(messageId);
49
+ if (existing && existing.ad_id === placement.ad_id) return prev;
50
+ const next = new Map(prev);
51
+ next.set(messageId, placement);
52
+ return next;
53
+ });
54
+ }
55
+ window.addEventListener("adzen_placement", handler);
56
+ return () => window.removeEventListener("adzen_placement", handler);
57
+ }, []);
58
+ const getAdForMessage = (0, import_react.useCallback)(
59
+ (messageId) => {
60
+ return placements.get(messageId) ?? null;
61
+ },
62
+ [placements]
63
+ );
64
+ return { getAdForMessage, placements };
65
+ }
66
+
67
+ // src/copilotkit/react/AdzenCard.tsx
68
+ var import_jsx_runtime = require("react/jsx-runtime");
69
+ function fireBeacon(url, body) {
70
+ fetch(url, {
71
+ method: "POST",
72
+ headers: { "Content-Type": "application/json" },
73
+ body
74
+ }).catch(() => {
75
+ setTimeout(() => {
76
+ fetch(url, {
77
+ method: "POST",
78
+ headers: { "Content-Type": "application/json" },
79
+ body
80
+ }).catch(() => {
81
+ });
82
+ }, 1e3);
83
+ });
84
+ }
85
+ function AdzenCard({
86
+ messageId,
87
+ adUnitPosition = "chin",
88
+ viewabilityThresholdMs = 1e3,
89
+ className,
90
+ impressionEndpoint
91
+ }) {
92
+ const { getAdForMessage } = useAdzenPlacement();
93
+ const ad = getAdForMessage(messageId);
94
+ const cardRef = (0, import_react2.useRef)(null);
95
+ const [renderFired, setRenderFired] = (0, import_react2.useState)(false);
96
+ const [viewed, setViewed] = (0, import_react2.useState)(false);
97
+ (0, import_react2.useEffect)(() => {
98
+ if (!ad || renderFired) return;
99
+ setRenderFired(true);
100
+ const url = impressionEndpoint ? `${impressionEndpoint}/impressions/render` : ad.tracking.render_url;
101
+ fireBeacon(
102
+ url,
103
+ JSON.stringify({
104
+ ad_id: ad.ad_id,
105
+ message_id: messageId,
106
+ ad_unit_position: adUnitPosition,
107
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
108
+ })
109
+ );
110
+ }, [ad, renderFired, messageId, adUnitPosition, impressionEndpoint]);
111
+ (0, import_react2.useEffect)(() => {
112
+ if (!ad || !cardRef.current || viewed) return;
113
+ return (0, import_core.observeViewability)({
114
+ element: cardRef.current,
115
+ thresholdMs: viewabilityThresholdMs,
116
+ onViewed: () => {
117
+ setViewed(true);
118
+ const url = impressionEndpoint ? `${impressionEndpoint}/impressions/view` : ad.tracking.view_url;
119
+ fireBeacon(
120
+ url,
121
+ JSON.stringify({
122
+ ad_id: ad.ad_id,
123
+ message_id: messageId,
124
+ ad_unit_position: adUnitPosition,
125
+ viewability_ms: viewabilityThresholdMs,
126
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
127
+ })
128
+ );
129
+ }
130
+ });
131
+ }, [ad, viewed, messageId, adUnitPosition, viewabilityThresholdMs, impressionEndpoint]);
132
+ if (!ad) return null;
133
+ const initial = ad.advertiser_name?.charAt(0).toUpperCase() ?? "?";
134
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
135
+ "div",
136
+ {
137
+ ref: cardRef,
138
+ className,
139
+ "data-adzen-ad-unit-position": adUnitPosition,
140
+ style: cardStyles.wrapper,
141
+ children: [
142
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: cardStyles.avatar, children: ad.advertiser_image_url ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
143
+ "img",
144
+ {
145
+ src: ad.advertiser_image_url,
146
+ alt: ad.advertiser_name,
147
+ style: cardStyles.avatarImg
148
+ }
149
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: cardStyles.avatarLetter, children: initial }) }),
150
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: cardStyles.content, children: [
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: cardStyles.topRow, children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: cardStyles.advertiserName, children: ad.advertiser_name }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: cardStyles.relevantAd, children: "Relevant Ad" })
154
+ ] }),
155
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: cardStyles.bottomRow, children: [
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: cardStyles.headline, children: ad.headline }),
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
158
+ "a",
159
+ {
160
+ href: ad.destination_url,
161
+ target: "_blank",
162
+ rel: "noopener sponsored",
163
+ style: cardStyles.cta,
164
+ children: ad.cta_text
165
+ }
166
+ )
167
+ ] })
168
+ ] })
169
+ ]
170
+ }
171
+ );
172
+ }
173
+ var cardStyles = {
174
+ wrapper: {
175
+ display: "flex",
176
+ alignItems: "center",
177
+ gap: "0.625rem",
178
+ fontSize: "0.85rem",
179
+ padding: "0.625rem 0.75rem"
180
+ },
181
+ avatar: {
182
+ width: 32,
183
+ height: 32,
184
+ borderRadius: "50%",
185
+ background: "#d1d5db",
186
+ display: "flex",
187
+ alignItems: "center",
188
+ justifyContent: "center",
189
+ flexShrink: 0,
190
+ overflow: "hidden"
191
+ },
192
+ avatarImg: {
193
+ width: "100%",
194
+ height: "100%",
195
+ objectFit: "cover",
196
+ borderRadius: "50%"
197
+ },
198
+ avatarLetter: {
199
+ fontSize: "0.8rem",
200
+ fontWeight: 700,
201
+ color: "#374151",
202
+ lineHeight: 1
203
+ },
204
+ content: {
205
+ display: "flex",
206
+ flexDirection: "column",
207
+ gap: "0.125rem",
208
+ minWidth: 0
209
+ },
210
+ topRow: {
211
+ display: "flex",
212
+ alignItems: "center",
213
+ gap: "0.5rem"
214
+ },
215
+ advertiserName: {
216
+ fontWeight: 700,
217
+ color: "inherit"
218
+ },
219
+ relevantAd: {
220
+ color: "#8b949e",
221
+ fontSize: "0.8rem"
222
+ },
223
+ bottomRow: {
224
+ display: "flex",
225
+ alignItems: "center",
226
+ gap: "0.5rem",
227
+ whiteSpace: "nowrap",
228
+ overflow: "hidden",
229
+ textOverflow: "ellipsis"
230
+ },
231
+ headline: {
232
+ overflow: "hidden",
233
+ textOverflow: "ellipsis"
234
+ },
235
+ cta: {
236
+ color: "#58a6ff",
237
+ textDecoration: "none",
238
+ fontWeight: 500,
239
+ flexShrink: 0
240
+ }
241
+ };
242
+
243
+ // src/copilotkit/react/bridge.ts
244
+ function dispatchPlacementEvent(event) {
245
+ if (typeof window === "undefined") return false;
246
+ if (event.name !== "adzen_placement") return false;
247
+ const type = String(event.type ?? "");
248
+ if (type !== "CUSTOM_EVENT" && type !== "CUSTOM" && type !== "CustomEvent")
249
+ return false;
250
+ const value = event.value;
251
+ if (!value) return false;
252
+ window.dispatchEvent(
253
+ new CustomEvent("adzen_placement", { detail: value })
254
+ );
255
+ return true;
256
+ }
257
+ function dispatchPlacementEvents(events) {
258
+ for (const event of events) {
259
+ dispatchPlacementEvent(event);
260
+ }
261
+ }
262
+ // Annotate the CommonJS export names for ESM import in node:
263
+ 0 && (module.exports = {
264
+ AdzenCard,
265
+ dispatchPlacementEvent,
266
+ dispatchPlacementEvents,
267
+ useAdzenPlacement
268
+ });
269
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/copilotkit/react/index.ts","../../../src/copilotkit/react/AdzenCard.tsx","../../../src/copilotkit/react/useAdzenPlacement.ts","../../../src/copilotkit/react/bridge.ts"],"sourcesContent":["export { AdzenCard } from \"./AdzenCard.js\";\nexport type { AdzenCardProps } from \"./AdzenCard.js\";\nexport { useAdzenPlacement } from \"./useAdzenPlacement.js\";\nexport type { UseAdzenPlacementReturn } from \"./useAdzenPlacement.js\";\nexport { dispatchPlacementEvent, dispatchPlacementEvents } from \"./bridge.js\";\n","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 impressionEndpoint?: string;\n}\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 impressionEndpoint,\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 const url = impressionEndpoint\n ? `${impressionEndpoint}/impressions/render`\n : ad.tracking.render_url;\n fireBeacon(\n url,\n JSON.stringify({\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, impressionEndpoint]);\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 const url = impressionEndpoint\n ? `${impressionEndpoint}/impressions/view`\n : ad.tracking.view_url;\n fireBeacon(\n url,\n JSON.stringify({\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, impressionEndpoint]);\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":["import_react"]}
@@ -0,0 +1,46 @@
1
+ import * as react from 'react';
2
+ import { AdzenPlacement } from '@adzenai/core';
3
+
4
+ interface AdzenCardProps {
5
+ messageId: string;
6
+ adUnitPosition?: string;
7
+ viewabilityThresholdMs?: number;
8
+ className?: string;
9
+ impressionEndpoint?: string;
10
+ }
11
+ /**
12
+ * Renders a sponsored ad card for a given assistant message. Returns `null`
13
+ * (no DOM output) when there is no ad for the message.
14
+ */
15
+ declare function AdzenCard({ messageId, adUnitPosition, viewabilityThresholdMs, className, impressionEndpoint, }: AdzenCardProps): react.JSX.Element | null;
16
+
17
+ interface UseAdzenPlacementReturn {
18
+ getAdForMessage(messageId: string): AdzenPlacement | null;
19
+ placements: Map<string, AdzenPlacement>;
20
+ }
21
+ /**
22
+ * React hook that subscribes to `adzen_placement` custom events and
23
+ * maintains a map of messageId -> AdzenPlacement.
24
+ *
25
+ * Works anywhere in the React tree below `<CopilotKit>` — no wrapper
26
+ * provider required.
27
+ */
28
+ declare function useAdzenPlacement(): UseAdzenPlacementReturn;
29
+
30
+ /**
31
+ * Checks whether an AG-UI event is an `adzen_placement` custom event
32
+ * and, if so, dispatches it as a browser `CustomEvent` on `window`
33
+ * so that `useAdzenPlacement` can pick it up.
34
+ *
35
+ * Call this for every event returned by `AdzenAsyncMiddleware.processEvent()`.
36
+ * Non-placement events are silently ignored.
37
+ */
38
+ declare function dispatchPlacementEvent(event: Record<string, unknown>): boolean;
39
+ /**
40
+ * Convenience wrapper: iterates an array of AG-UI events (as returned by
41
+ * `AdzenAsyncMiddleware.processEvent()`) and dispatches any placement
42
+ * events to the browser.
43
+ */
44
+ declare function dispatchPlacementEvents(events: Record<string, unknown>[]): void;
45
+
46
+ export { AdzenCard, type AdzenCardProps, type UseAdzenPlacementReturn, dispatchPlacementEvent, dispatchPlacementEvents, useAdzenPlacement };
@@ -0,0 +1,46 @@
1
+ import * as react from 'react';
2
+ import { AdzenPlacement } from '@adzenai/core';
3
+
4
+ interface AdzenCardProps {
5
+ messageId: string;
6
+ adUnitPosition?: string;
7
+ viewabilityThresholdMs?: number;
8
+ className?: string;
9
+ impressionEndpoint?: string;
10
+ }
11
+ /**
12
+ * Renders a sponsored ad card for a given assistant message. Returns `null`
13
+ * (no DOM output) when there is no ad for the message.
14
+ */
15
+ declare function AdzenCard({ messageId, adUnitPosition, viewabilityThresholdMs, className, impressionEndpoint, }: AdzenCardProps): react.JSX.Element | null;
16
+
17
+ interface UseAdzenPlacementReturn {
18
+ getAdForMessage(messageId: string): AdzenPlacement | null;
19
+ placements: Map<string, AdzenPlacement>;
20
+ }
21
+ /**
22
+ * React hook that subscribes to `adzen_placement` custom events and
23
+ * maintains a map of messageId -> AdzenPlacement.
24
+ *
25
+ * Works anywhere in the React tree below `<CopilotKit>` — no wrapper
26
+ * provider required.
27
+ */
28
+ declare function useAdzenPlacement(): UseAdzenPlacementReturn;
29
+
30
+ /**
31
+ * Checks whether an AG-UI event is an `adzen_placement` custom event
32
+ * and, if so, dispatches it as a browser `CustomEvent` on `window`
33
+ * so that `useAdzenPlacement` can pick it up.
34
+ *
35
+ * Call this for every event returned by `AdzenAsyncMiddleware.processEvent()`.
36
+ * Non-placement events are silently ignored.
37
+ */
38
+ declare function dispatchPlacementEvent(event: Record<string, unknown>): boolean;
39
+ /**
40
+ * Convenience wrapper: iterates an array of AG-UI events (as returned by
41
+ * `AdzenAsyncMiddleware.processEvent()`) and dispatches any placement
42
+ * events to the browser.
43
+ */
44
+ declare function dispatchPlacementEvents(events: Record<string, unknown>[]): void;
45
+
46
+ export { AdzenCard, type AdzenCardProps, type UseAdzenPlacementReturn, dispatchPlacementEvent, dispatchPlacementEvents, useAdzenPlacement };
@@ -0,0 +1,239 @@
1
+ // src/copilotkit/react/AdzenCard.tsx
2
+ import { useRef, useEffect as useEffect2, useState as useState2 } from "react";
3
+ import { observeViewability } from "@adzenai/core";
4
+
5
+ // src/copilotkit/react/useAdzenPlacement.ts
6
+ import { useState, useEffect, useCallback } from "react";
7
+ function useAdzenPlacement() {
8
+ const [placements, setPlacements] = useState(
9
+ () => /* @__PURE__ */ new Map()
10
+ );
11
+ useEffect(() => {
12
+ function handler(e) {
13
+ const detail = e.detail;
14
+ if (!detail || typeof detail !== "object") return;
15
+ const placement = detail;
16
+ const messageId = placement.message_id;
17
+ if (!messageId) return;
18
+ setPlacements((prev) => {
19
+ const existing = prev.get(messageId);
20
+ if (existing && existing.ad_id === placement.ad_id) return prev;
21
+ const next = new Map(prev);
22
+ next.set(messageId, placement);
23
+ return next;
24
+ });
25
+ }
26
+ window.addEventListener("adzen_placement", handler);
27
+ return () => window.removeEventListener("adzen_placement", handler);
28
+ }, []);
29
+ const getAdForMessage = useCallback(
30
+ (messageId) => {
31
+ return placements.get(messageId) ?? null;
32
+ },
33
+ [placements]
34
+ );
35
+ return { getAdForMessage, placements };
36
+ }
37
+
38
+ // src/copilotkit/react/AdzenCard.tsx
39
+ import { jsx, jsxs } from "react/jsx-runtime";
40
+ function fireBeacon(url, body) {
41
+ fetch(url, {
42
+ method: "POST",
43
+ headers: { "Content-Type": "application/json" },
44
+ body
45
+ }).catch(() => {
46
+ setTimeout(() => {
47
+ fetch(url, {
48
+ method: "POST",
49
+ headers: { "Content-Type": "application/json" },
50
+ body
51
+ }).catch(() => {
52
+ });
53
+ }, 1e3);
54
+ });
55
+ }
56
+ function AdzenCard({
57
+ messageId,
58
+ adUnitPosition = "chin",
59
+ viewabilityThresholdMs = 1e3,
60
+ className,
61
+ impressionEndpoint
62
+ }) {
63
+ const { getAdForMessage } = useAdzenPlacement();
64
+ const ad = getAdForMessage(messageId);
65
+ const cardRef = useRef(null);
66
+ const [renderFired, setRenderFired] = useState2(false);
67
+ const [viewed, setViewed] = useState2(false);
68
+ useEffect2(() => {
69
+ if (!ad || renderFired) return;
70
+ setRenderFired(true);
71
+ const url = impressionEndpoint ? `${impressionEndpoint}/impressions/render` : ad.tracking.render_url;
72
+ fireBeacon(
73
+ url,
74
+ JSON.stringify({
75
+ ad_id: ad.ad_id,
76
+ message_id: messageId,
77
+ ad_unit_position: adUnitPosition,
78
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
79
+ })
80
+ );
81
+ }, [ad, renderFired, messageId, adUnitPosition, impressionEndpoint]);
82
+ useEffect2(() => {
83
+ if (!ad || !cardRef.current || viewed) return;
84
+ return observeViewability({
85
+ element: cardRef.current,
86
+ thresholdMs: viewabilityThresholdMs,
87
+ onViewed: () => {
88
+ setViewed(true);
89
+ const url = impressionEndpoint ? `${impressionEndpoint}/impressions/view` : ad.tracking.view_url;
90
+ fireBeacon(
91
+ url,
92
+ JSON.stringify({
93
+ ad_id: ad.ad_id,
94
+ message_id: messageId,
95
+ ad_unit_position: adUnitPosition,
96
+ viewability_ms: viewabilityThresholdMs,
97
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
98
+ })
99
+ );
100
+ }
101
+ });
102
+ }, [ad, viewed, messageId, adUnitPosition, viewabilityThresholdMs, impressionEndpoint]);
103
+ if (!ad) return null;
104
+ const initial = ad.advertiser_name?.charAt(0).toUpperCase() ?? "?";
105
+ return /* @__PURE__ */ jsxs(
106
+ "div",
107
+ {
108
+ ref: cardRef,
109
+ className,
110
+ "data-adzen-ad-unit-position": adUnitPosition,
111
+ style: cardStyles.wrapper,
112
+ children: [
113
+ /* @__PURE__ */ jsx("div", { style: cardStyles.avatar, children: ad.advertiser_image_url ? /* @__PURE__ */ jsx(
114
+ "img",
115
+ {
116
+ src: ad.advertiser_image_url,
117
+ alt: ad.advertiser_name,
118
+ style: cardStyles.avatarImg
119
+ }
120
+ ) : /* @__PURE__ */ jsx("span", { style: cardStyles.avatarLetter, children: initial }) }),
121
+ /* @__PURE__ */ jsxs("div", { style: cardStyles.content, children: [
122
+ /* @__PURE__ */ jsxs("div", { style: cardStyles.topRow, children: [
123
+ /* @__PURE__ */ jsx("span", { style: cardStyles.advertiserName, children: ad.advertiser_name }),
124
+ /* @__PURE__ */ jsx("span", { style: cardStyles.relevantAd, children: "Relevant Ad" })
125
+ ] }),
126
+ /* @__PURE__ */ jsxs("div", { style: cardStyles.bottomRow, children: [
127
+ /* @__PURE__ */ jsx("span", { style: cardStyles.headline, children: ad.headline }),
128
+ /* @__PURE__ */ jsx(
129
+ "a",
130
+ {
131
+ href: ad.destination_url,
132
+ target: "_blank",
133
+ rel: "noopener sponsored",
134
+ style: cardStyles.cta,
135
+ children: ad.cta_text
136
+ }
137
+ )
138
+ ] })
139
+ ] })
140
+ ]
141
+ }
142
+ );
143
+ }
144
+ var cardStyles = {
145
+ wrapper: {
146
+ display: "flex",
147
+ alignItems: "center",
148
+ gap: "0.625rem",
149
+ fontSize: "0.85rem",
150
+ padding: "0.625rem 0.75rem"
151
+ },
152
+ avatar: {
153
+ width: 32,
154
+ height: 32,
155
+ borderRadius: "50%",
156
+ background: "#d1d5db",
157
+ display: "flex",
158
+ alignItems: "center",
159
+ justifyContent: "center",
160
+ flexShrink: 0,
161
+ overflow: "hidden"
162
+ },
163
+ avatarImg: {
164
+ width: "100%",
165
+ height: "100%",
166
+ objectFit: "cover",
167
+ borderRadius: "50%"
168
+ },
169
+ avatarLetter: {
170
+ fontSize: "0.8rem",
171
+ fontWeight: 700,
172
+ color: "#374151",
173
+ lineHeight: 1
174
+ },
175
+ content: {
176
+ display: "flex",
177
+ flexDirection: "column",
178
+ gap: "0.125rem",
179
+ minWidth: 0
180
+ },
181
+ topRow: {
182
+ display: "flex",
183
+ alignItems: "center",
184
+ gap: "0.5rem"
185
+ },
186
+ advertiserName: {
187
+ fontWeight: 700,
188
+ color: "inherit"
189
+ },
190
+ relevantAd: {
191
+ color: "#8b949e",
192
+ fontSize: "0.8rem"
193
+ },
194
+ bottomRow: {
195
+ display: "flex",
196
+ alignItems: "center",
197
+ gap: "0.5rem",
198
+ whiteSpace: "nowrap",
199
+ overflow: "hidden",
200
+ textOverflow: "ellipsis"
201
+ },
202
+ headline: {
203
+ overflow: "hidden",
204
+ textOverflow: "ellipsis"
205
+ },
206
+ cta: {
207
+ color: "#58a6ff",
208
+ textDecoration: "none",
209
+ fontWeight: 500,
210
+ flexShrink: 0
211
+ }
212
+ };
213
+
214
+ // src/copilotkit/react/bridge.ts
215
+ function dispatchPlacementEvent(event) {
216
+ if (typeof window === "undefined") return false;
217
+ if (event.name !== "adzen_placement") return false;
218
+ const type = String(event.type ?? "");
219
+ if (type !== "CUSTOM_EVENT" && type !== "CUSTOM" && type !== "CustomEvent")
220
+ return false;
221
+ const value = event.value;
222
+ if (!value) return false;
223
+ window.dispatchEvent(
224
+ new CustomEvent("adzen_placement", { detail: value })
225
+ );
226
+ return true;
227
+ }
228
+ function dispatchPlacementEvents(events) {
229
+ for (const event of events) {
230
+ dispatchPlacementEvent(event);
231
+ }
232
+ }
233
+ export {
234
+ AdzenCard,
235
+ dispatchPlacementEvent,
236
+ dispatchPlacementEvents,
237
+ useAdzenPlacement
238
+ };
239
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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 impressionEndpoint?: string;\n}\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 impressionEndpoint,\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 const url = impressionEndpoint\n ? `${impressionEndpoint}/impressions/render`\n : ad.tracking.render_url;\n fireBeacon(\n url,\n JSON.stringify({\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, impressionEndpoint]);\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 const url = impressionEndpoint\n ? `${impressionEndpoint}/impressions/view`\n : ad.tracking.view_url;\n fireBeacon(\n url,\n JSON.stringify({\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, impressionEndpoint]);\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":";AAAA,SAAS,QAAQ,aAAAA,YAAW,YAAAC,iBAAgB;AAC5C,SAAS,0BAA0B;;;ACDnC,SAAS,UAAU,WAAW,mBAAmB;AAe1C,SAAS,oBAA6C;AAC3D,QAAM,CAAC,YAAY,aAAa,IAAI;AAAA,IAClC,MAAM,oBAAI,IAAI;AAAA,EAChB;AAEA,YAAU,MAAM;AACd,aAAS,QAAQ,GAAU;AACzB,YAAM,SAAU,EAAkB;AAClC,UAAI,CAAC,UAAU,OAAO,WAAW,SAAU;AAE3C,YAAM,YAAY;AAClB,YAAM,YAAY,UAAU;AAC5B,UAAI,CAAC,UAAW;AAEhB,oBAAc,CAAC,SAAS;AACtB,cAAM,WAAW,KAAK,IAAI,SAAS;AACnC,YAAI,YAAY,SAAS,UAAU,UAAU,MAAO,QAAO;AAC3D,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,IAAI,WAAW,SAAS;AAC7B,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO,iBAAiB,mBAAmB,OAAO;AAClD,WAAO,MAAM,OAAO,oBAAoB,mBAAmB,OAAO;AAAA,EACpE,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkB;AAAA,IACtB,CAAC,cAA6C;AAC5C,aAAO,WAAW,IAAI,SAAS,KAAK;AAAA,IACtC;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAEA,SAAO,EAAE,iBAAiB,WAAW;AACvC;;;ADmDU,cAWF,YAXE;AAzFV,SAAS,WAAW,KAAa,MAAoB;AACnD,QAAM,KAAK;AAAA,IACT,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C;AAAA,EACF,CAAC,EAAE,MAAM,MAAM;AACb,eAAW,MAAM;AACf,YAAM,KAAK;AAAA,QACT,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C;AAAA,MACF,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB,GAAG,GAAI;AAAA,EACT,CAAC;AACH;AAMO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,EAAE,gBAAgB,IAAI,kBAAkB;AAC9C,QAAM,KAAK,gBAAgB,SAAS;AACpC,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,CAAC,aAAa,cAAc,IAAIC,UAAS,KAAK;AACpD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAE1C,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,MAAM,YAAa;AACxB,mBAAe,IAAI;AAEnB,UAAM,MAAM,qBACR,GAAG,kBAAkB,wBACrB,GAAG,SAAS;AAChB;AAAA,MACE;AAAA,MACA,KAAK,UAAU;AAAA,QACb,OAAO,GAAG;AAAA,QACV,YAAY;AAAA,QACZ,kBAAkB;AAAA,QAClB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,IAAI,aAAa,WAAW,gBAAgB,kBAAkB,CAAC;AAEnE,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,MAAM,CAAC,QAAQ,WAAW,OAAQ;AAEvC,WAAO,mBAAmB;AAAA,MACxB,SAAS,QAAQ;AAAA,MACjB,aAAa;AAAA,MACb,UAAU,MAAM;AACd,kBAAU,IAAI;AACd,cAAM,MAAM,qBACR,GAAG,kBAAkB,sBACrB,GAAG,SAAS;AAChB;AAAA,UACE;AAAA,UACA,KAAK,UAAU;AAAA,YACb,OAAO,GAAG;AAAA,YACV,YAAY;AAAA,YACZ,kBAAkB;AAAA,YAClB,gBAAgB;AAAA,YAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,IAAI,QAAQ,WAAW,gBAAgB,wBAAwB,kBAAkB,CAAC;AAEtF,MAAI,CAAC,GAAI,QAAO;AAEhB,QAAM,UAAU,GAAG,iBAAiB,OAAO,CAAC,EAAE,YAAY,KAAK;AAE/D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL;AAAA,MACA,+BAA6B;AAAA,MAC7B,OAAO,WAAW;AAAA,MAElB;AAAA,4BAAC,SAAI,OAAO,WAAW,QACpB,aAAG,uBACF;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,GAAG;AAAA,YACR,KAAK,GAAG;AAAA,YACR,OAAO,WAAW;AAAA;AAAA,QACpB,IAEA,oBAAC,UAAK,OAAO,WAAW,cAAe,mBAAQ,GAEnD;AAAA,QAEA,qBAAC,SAAI,OAAO,WAAW,SACrB;AAAA,+BAAC,SAAI,OAAO,WAAW,QACrB;AAAA,gCAAC,UAAK,OAAO,WAAW,gBAAiB,aAAG,iBAAgB;AAAA,YAC5D,oBAAC,UAAK,OAAO,WAAW,YAAY,yBAAW;AAAA,aACjD;AAAA,UACA,qBAAC,SAAI,OAAO,WAAW,WACrB;AAAA,gCAAC,UAAK,OAAO,WAAW,UAAW,aAAG,UAAS;AAAA,YAC/C;AAAA,cAAC;AAAA;AAAA,gBACC,MAAM,GAAG;AAAA,gBACT,QAAO;AAAA,gBACP,KAAI;AAAA,gBACJ,OAAO,WAAW;AAAA,gBAEjB,aAAG;AAAA;AAAA,YACN;AAAA,aACF;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAM,aAAkD;AAAA,EACtD,SAAS;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,cAAc;AAAA,EAChB;AAAA,EACA,cAAc;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,SAAS;AAAA,IACT,eAAe;AAAA,IACf,KAAK;AAAA,IACL,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,EACP;AAAA,EACA,gBAAgB;AAAA,IACd,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAAA,EACA,UAAU;AAAA,IACR,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAAA,EACA,KAAK;AAAA,IACH,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACF;;;AE9LO,SAAS,uBACd,OACS;AACT,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI,MAAM,SAAS,kBAAmB,QAAO;AAE7C,QAAM,OAAO,OAAO,MAAM,QAAQ,EAAE;AACpC,MAAI,SAAS,kBAAkB,SAAS,YAAY,SAAS;AAC3D,WAAO;AAET,QAAM,QAAQ,MAAM;AACpB,MAAI,CAAC,MAAO,QAAO;AAEnB,SAAO;AAAA,IACL,IAAI,YAAY,mBAAmB,EAAE,QAAQ,MAAM,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAOO,SAAS,wBACd,QACM;AACN,aAAW,SAAS,QAAQ;AAC1B,2BAAuB,KAAK;AAAA,EAC9B;AACF;","names":["useEffect","useState","useState","useEffect"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/index.ts
17
+ var index_exports = {};
18
+ module.exports = __toCommonJS(index_exports);
19
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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":[]}
@@ -0,0 +1 @@
1
+ export { AdzenBaseConfig, AdzenDecision, AdzenPlacement, TrackingInfo } from '@adzenai/core';
@@ -0,0 +1 @@
1
+ export { AdzenBaseConfig, AdzenDecision, AdzenPlacement, TrackingInfo } from '@adzenai/core';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@adzenai/ai",
3
+ "version": "0.0.1",
4
+ "description": "AI-powered ad integration for CopilotKit and AG-UI agents",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "import": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "require": {
17
+ "types": "./dist/index.d.cts",
18
+ "default": "./dist/index.cjs"
19
+ }
20
+ },
21
+ "./copilotkit": {
22
+ "import": {
23
+ "types": "./dist/copilotkit/index.d.ts",
24
+ "default": "./dist/copilotkit/index.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/copilotkit/index.d.cts",
28
+ "default": "./dist/copilotkit/index.cjs"
29
+ }
30
+ },
31
+ "./copilotkit/react": {
32
+ "import": {
33
+ "types": "./dist/copilotkit/react/index.d.ts",
34
+ "default": "./dist/copilotkit/react/index.js"
35
+ },
36
+ "require": {
37
+ "types": "./dist/copilotkit/react/index.d.cts",
38
+ "default": "./dist/copilotkit/react/index.cjs"
39
+ }
40
+ }
41
+ },
42
+ "main": "./dist/index.cjs",
43
+ "module": "./dist/index.js",
44
+ "types": "./dist/index.d.ts",
45
+ "files": [
46
+ "dist"
47
+ ],
48
+ "scripts": {
49
+ "build": "tsup",
50
+ "test": "vitest run",
51
+ "clean": "rm -rf dist",
52
+ "typecheck": "tsc --noEmit",
53
+ "demo": "vite --config src/copilotkit/demo/vite.config.ts"
54
+ },
55
+ "dependencies": {
56
+ "@adzenai/core": "workspace:*"
57
+ },
58
+ "peerDependencies": {
59
+ "@ag-ui/client": "*",
60
+ "@ag-ui/core": "*",
61
+ "react": ">=18",
62
+ "rxjs": ">=7"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "react": {
66
+ "optional": true
67
+ },
68
+ "@ag-ui/client": {
69
+ "optional": true
70
+ },
71
+ "@ag-ui/core": {
72
+ "optional": true
73
+ },
74
+ "rxjs": {
75
+ "optional": true
76
+ }
77
+ },
78
+ "devDependencies": {
79
+ "@types/react": "^18.3.0",
80
+ "@types/react-dom": "^18.3.0",
81
+ "@vitejs/plugin-react": "^4.3.0",
82
+ "jsdom": "^29.1.1",
83
+ "react": "^18.3.0",
84
+ "react-dom": "^18.3.0",
85
+ "tsup": "^8.1.0",
86
+ "typescript": "^5.5.0",
87
+ "vite": "^6.0.0",
88
+ "vitest": "^2.1.0"
89
+ }
90
+ }