@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.
- package/dist/copilotkit/index.cjs +198 -0
- package/dist/copilotkit/index.cjs.map +1 -0
- package/dist/copilotkit/index.d.cts +35 -0
- package/dist/copilotkit/index.d.ts +35 -0
- package/dist/copilotkit/index.js +171 -0
- package/dist/copilotkit/index.js.map +1 -0
- package/dist/copilotkit/react/index.cjs +269 -0
- package/dist/copilotkit/react/index.cjs.map +1 -0
- package/dist/copilotkit/react/index.d.cts +46 -0
- package/dist/copilotkit/react/index.d.ts +46 -0
- package/dist/copilotkit/react/index.js +239 -0
- package/dist/copilotkit/react/index.js.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/package.json +90 -0
|
@@ -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":"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","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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAA4C;AAC5C,kBAAmC;;;ACDnC,mBAAiD;AAe1C,SAAS,oBAA6C;AAC3D,QAAM,CAAC,YAAY,aAAa,QAAI;AAAA,IAClC,MAAM,oBAAI,IAAI;AAAA,EAChB;AAEA,8BAAU,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,sBAAkB;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;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,cAAU,sBAAuB,IAAI;AAC3C,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AACpD,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAE1C,+BAAU,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,+BAAU,MAAM;AACd,QAAI,CAAC,MAAM,CAAC,QAAQ,WAAW,OAAQ;AAEvC,eAAO,gCAAmB;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,oDAAC,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,4CAAC,UAAK,OAAO,WAAW,cAAe,mBAAQ,GAEnD;AAAA,QAEA,6CAAC,SAAI,OAAO,WAAW,SACrB;AAAA,uDAAC,SAAI,OAAO,WAAW,QACrB;AAAA,wDAAC,UAAK,OAAO,WAAW,gBAAiB,aAAG,iBAAgB;AAAA,YAC5D,4CAAC,UAAK,OAAO,WAAW,YAAY,yBAAW;AAAA,aACjD;AAAA,UACA,6CAAC,SAAI,OAAO,WAAW,WACrB;AAAA,wDAAC,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":["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":"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","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":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AdzenBaseConfig, AdzenDecision, AdzenPlacement, TrackingInfo } from '@adzenai/core';
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|