@copilotkit/shared 1.57.3 → 1.58.0-canary.thread-id-propagation

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.
Files changed (44) hide show
  1. package/dist/index.cjs +5 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +2 -1
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.mts +2 -1
  6. package/dist/index.d.mts.map +1 -1
  7. package/dist/index.mjs +3 -2
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/index.umd.js +98 -33
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/package.cjs +1 -1
  12. package/dist/package.mjs +1 -1
  13. package/dist/telemetry/index.d.mts +2 -1
  14. package/dist/telemetry/lambda-client.cjs +70 -0
  15. package/dist/telemetry/lambda-client.cjs.map +1 -0
  16. package/dist/telemetry/lambda-client.d.cts +18 -0
  17. package/dist/telemetry/lambda-client.d.cts.map +1 -0
  18. package/dist/telemetry/lambda-client.d.mts +18 -0
  19. package/dist/telemetry/lambda-client.d.mts.map +1 -0
  20. package/dist/telemetry/lambda-client.mjs +67 -0
  21. package/dist/telemetry/lambda-client.mjs.map +1 -0
  22. package/dist/telemetry/telemetry-client.cjs +29 -10
  23. package/dist/telemetry/telemetry-client.cjs.map +1 -1
  24. package/dist/telemetry/telemetry-client.d.cts +3 -0
  25. package/dist/telemetry/telemetry-client.d.cts.map +1 -1
  26. package/dist/telemetry/telemetry-client.d.mts +3 -0
  27. package/dist/telemetry/telemetry-client.d.mts.map +1 -1
  28. package/dist/telemetry/telemetry-client.mjs +29 -10
  29. package/dist/telemetry/telemetry-client.mjs.map +1 -1
  30. package/dist/utils/console-styling.cjs +1 -1
  31. package/dist/utils/console-styling.cjs.map +1 -1
  32. package/dist/utils/console-styling.mjs +1 -1
  33. package/dist/utils/console-styling.mjs.map +1 -1
  34. package/package.json +1 -1
  35. package/src/telemetry/index.ts +6 -0
  36. package/src/telemetry/lambda-client.test.ts +111 -0
  37. package/src/telemetry/lambda-client.ts +153 -0
  38. package/src/telemetry/telemetry-client.test.ts +289 -0
  39. package/src/telemetry/telemetry-client.ts +67 -15
  40. package/src/utils/console-styling.ts +1 -1
  41. package/dist/telemetry/scarf-client.cjs +0 -29
  42. package/dist/telemetry/scarf-client.cjs.map +0 -1
  43. package/dist/telemetry/scarf-client.mjs +0 -29
  44. package/dist/telemetry/scarf-client.mjs.map +0 -1
@@ -0,0 +1,70 @@
1
+
2
+ //#region src/telemetry/lambda-client.ts
3
+ const TELEMETRY_SINK_URL = typeof process !== "undefined" && process.env?.COPILOTKIT_TELEMETRY_URL || "https://telemetry.copilotkit.ai/ingest";
4
+ const FETCH_TIMEOUT_MS = 3e3;
5
+ const STRIPPED_KEYS = new Set(["cloud.public_api_key", "cloud.publicApiKey"]);
6
+ function stripCloudKeys(obj) {
7
+ if (!obj) return {};
8
+ const out = {};
9
+ for (const [k, v] of Object.entries(obj)) if (!STRIPPED_KEYS.has(k)) out[k] = v;
10
+ return out;
11
+ }
12
+ function parseTelemetryIdFromLicense(token) {
13
+ if (!token) return null;
14
+ const parts = token.split(".");
15
+ if (parts.length !== 3) return null;
16
+ try {
17
+ let b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
18
+ const padding = (4 - b64.length % 4) % 4;
19
+ b64 += "=".repeat(padding);
20
+ const json = typeof atob === "function" ? atob(b64) : Buffer.from(b64, "base64").toString("utf8");
21
+ const decoded = JSON.parse(json);
22
+ return typeof decoded.telemetry_id === "string" ? decoded.telemetry_id : null;
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+ function parseAndWarnTelemetryId(licenseToken) {
28
+ const telemetryId = parseTelemetryIdFromLicense(licenseToken);
29
+ if (!telemetryId) console.warn("[CopilotKit] License token did not yield a telemetry_id; telemetry events will be sent anonymously.");
30
+ return telemetryId;
31
+ }
32
+ async function send(opts) {
33
+ try {
34
+ const body = JSON.stringify({
35
+ event: opts.event,
36
+ properties: stripCloudKeys(opts.properties),
37
+ global_properties: stripCloudKeys(opts.globalProperties),
38
+ package: {
39
+ name: opts.packageName,
40
+ version: opts.packageVersion
41
+ },
42
+ ts: Math.floor(Date.now() / 1e3)
43
+ });
44
+ const telemetryId = parseTelemetryIdFromLicense(opts.licenseToken);
45
+ const headers = {
46
+ "Content-Type": "application/json",
47
+ "User-Agent": opts.packageName ? `CopilotKit-Runtime/${opts.packageVersion ?? "unknown"} (${opts.packageName})` : "CopilotKit-Runtime"
48
+ };
49
+ if (telemetryId) headers["X-CopilotKit-Telemetry-Id"] = telemetryId;
50
+ const controller = new AbortController();
51
+ const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
52
+ try {
53
+ await fetch(TELEMETRY_SINK_URL, {
54
+ method: "POST",
55
+ headers,
56
+ body,
57
+ signal: controller.signal
58
+ });
59
+ } finally {
60
+ clearTimeout(timeoutId);
61
+ }
62
+ } catch {}
63
+ }
64
+ var lambda_client_default = { send };
65
+
66
+ //#endregion
67
+ exports.default = lambda_client_default;
68
+ exports.parseAndWarnTelemetryId = parseAndWarnTelemetryId;
69
+ exports.parseTelemetryIdFromLicense = parseTelemetryIdFromLicense;
70
+ //# sourceMappingURL=lambda-client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambda-client.cjs","names":[],"sources":["../../src/telemetry/lambda-client.ts"],"sourcesContent":["// Telemetry sink client.\n//\n// Posts events to a CopilotKit-controlled telemetry-sink endpoint, which\n// fans out to Scarf, Reo, and any future destinations. Replaces the direct\n// per-vendor calls (scarf-client.ts) so that vendor changes don't require\n// SDK releases and so that downstream services we don't want exposed to\n// OSS readers (e.g. the email-enrichment service backing Reo) stay\n// private.\n//\n// Two attribution modes:\n// - Identified: a CopilotKit license token is configured. The token is\n// a JWT (header.payload.sig) whose payload carries `telemetry_id`.\n// The SDK base64url-decodes the payload — without verifying the\n// Ed25519 signature, which is the license-verifier's job — and\n// emits the id via `X-CopilotKit-Telemetry-Id`. The Lambda uses it\n// to enrich events with the customer's email.\n// - Anonymous: no license token, or a malformed/non-JWT one. No\n// telemetry-id header; events still flow, attribution is best-effort\n// from request-level signals (IP, UA).\n//\n// Note: CopilotCloud customer API keys (`ck_<env>_<id>.<secret>`) are\n// unrelated to telemetry attribution. They flow into Segment / PostHog\n// via the v1 shared TelemetryClient and never reach this code path.\n//\n// Best-effort: every error is swallowed. Telemetry must not break the\n// host application.\n\nconst TELEMETRY_SINK_URL =\n (typeof process !== \"undefined\" && process.env?.COPILOTKIT_TELEMETRY_URL) ||\n \"https://telemetry.copilotkit.ai/ingest\";\n\nconst FETCH_TIMEOUT_MS = 3000;\n\nexport interface LambdaSendOptions {\n event: string;\n properties?: Record<string, unknown>;\n globalProperties?: Record<string, unknown>;\n packageName?: string;\n packageVersion?: string;\n // The CopilotKit license token (Ed25519-signed JWT), when one is\n // configured on the runtime. The sender base64url-decodes the payload\n // segment to extract `telemetry_id`; missing or malformed tokens\n // produce an anonymous send.\n licenseToken?: string;\n}\n\n// These fields aren't used by the telemetry service, so we strip them\n// at the wire boundary rather than rely on every caller to omit them.\n// Both the snake_case and camelCase variants are listed because callers\n// upstream use different conventions.\nconst STRIPPED_KEYS = new Set([\"cloud.public_api_key\", \"cloud.publicApiKey\"]);\n\nfunction stripCloudKeys(\n obj: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n if (!obj) return {};\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (!STRIPPED_KEYS.has(k)) out[k] = v;\n }\n return out;\n}\n\n// Pull telemetry_id out of a CopilotKit license token without verifying\n// the signature. The token shape is a standard JWT\n// (`<header>.<payload>.<sig>`) with base64url-encoded segments; the\n// payload is JSON with a `telemetry_id` string field.\n//\n// Verification (Ed25519, key rotation, expiry) is the license-verifier\n// package's job. For telemetry attribution we only need the claimed id —\n// the trust model is claim-only on the Lambda side anyway.\n//\n// Exported so TelemetryClient setters can detect unparseable tokens at\n// configuration time and surface a single warning, instead of silently\n// emitting anonymous events on every capture.\nexport function parseTelemetryIdFromLicense(token?: string): string | null {\n if (!token) return null;\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n try {\n let b64 = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = (4 - (b64.length % 4)) % 4;\n b64 += \"=\".repeat(padding);\n const json =\n typeof atob === \"function\"\n ? atob(b64)\n : Buffer.from(b64, \"base64\").toString(\"utf8\");\n const decoded = JSON.parse(json) as { telemetry_id?: unknown };\n return typeof decoded.telemetry_id === \"string\"\n ? decoded.telemetry_id\n : null;\n } catch {\n return null;\n }\n}\n\n// Parse the telemetry_id from a license token AND emit the rollout smoke\n// signal if the parse returned null. Returning the parsed id lets callers\n// cache it in one step (avoiding a second parseTelemetryIdFromLicense\n// pass) while keeping the warn text in lockstep between v1 (shared) and\n// v2 (runtime) TelemetryClient.setLicenseToken.\nexport function parseAndWarnTelemetryId(licenseToken: string): string | null {\n const telemetryId = parseTelemetryIdFromLicense(licenseToken);\n if (!telemetryId) {\n console.warn(\n \"[CopilotKit] License token did not yield a telemetry_id; telemetry events will be sent anonymously.\",\n );\n }\n return telemetryId;\n}\n\nexport async function send(opts: LambdaSendOptions): Promise<void> {\n try {\n const body = JSON.stringify({\n event: opts.event,\n properties: stripCloudKeys(opts.properties),\n global_properties: stripCloudKeys(opts.globalProperties),\n package: {\n name: opts.packageName,\n version: opts.packageVersion,\n },\n ts: Math.floor(Date.now() / 1000),\n });\n\n const telemetryId = parseTelemetryIdFromLicense(opts.licenseToken);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"User-Agent\": opts.packageName\n ? `CopilotKit-Runtime/${opts.packageVersion ?? \"unknown\"} (${opts.packageName})`\n : \"CopilotKit-Runtime\",\n };\n if (telemetryId) {\n headers[\"X-CopilotKit-Telemetry-Id\"] = telemetryId;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n try {\n await fetch(TELEMETRY_SINK_URL, {\n method: \"POST\",\n headers,\n body,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n } catch {\n // Silent failure — telemetry must not break the application.\n }\n}\n\nexport default { send };\n"],"mappings":";;AA2BA,MAAM,qBACH,OAAO,YAAY,eAAe,QAAQ,KAAK,4BAChD;AAEF,MAAM,mBAAmB;AAmBzB,MAAM,gBAAgB,IAAI,IAAI,CAAC,wBAAwB,qBAAqB,CAAC;AAE7E,SAAS,eACP,KACyB;AACzB,KAAI,CAAC,IAAK,QAAO,EAAE;CACnB,MAAM,MAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI,CACtC,KAAI,CAAC,cAAc,IAAI,EAAE,CAAE,KAAI,KAAK;AAEtC,QAAO;;AAeT,SAAgB,4BAA4B,OAA+B;AACzE,KAAI,CAAC,MAAO,QAAO;CACnB,MAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,KAAI;EACF,IAAI,MAAM,MAAM,GAAG,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI;EACxD,MAAM,WAAW,IAAK,IAAI,SAAS,KAAM;AACzC,SAAO,IAAI,OAAO,QAAQ;EAC1B,MAAM,OACJ,OAAO,SAAS,aACZ,KAAK,IAAI,GACT,OAAO,KAAK,KAAK,SAAS,CAAC,SAAS,OAAO;EACjD,MAAM,UAAU,KAAK,MAAM,KAAK;AAChC,SAAO,OAAO,QAAQ,iBAAiB,WACnC,QAAQ,eACR;SACE;AACN,SAAO;;;AASX,SAAgB,wBAAwB,cAAqC;CAC3E,MAAM,cAAc,4BAA4B,aAAa;AAC7D,KAAI,CAAC,YACH,SAAQ,KACN,sGACD;AAEH,QAAO;;AAGT,eAAsB,KAAK,MAAwC;AACjE,KAAI;EACF,MAAM,OAAO,KAAK,UAAU;GAC1B,OAAO,KAAK;GACZ,YAAY,eAAe,KAAK,WAAW;GAC3C,mBAAmB,eAAe,KAAK,iBAAiB;GACxD,SAAS;IACP,MAAM,KAAK;IACX,SAAS,KAAK;IACf;GACD,IAAI,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAClC,CAAC;EAEF,MAAM,cAAc,4BAA4B,KAAK,aAAa;EAClE,MAAM,UAAkC;GACtC,gBAAgB;GAChB,cAAc,KAAK,cACf,sBAAsB,KAAK,kBAAkB,UAAU,IAAI,KAAK,YAAY,KAC5E;GACL;AACD,MAAI,YACF,SAAQ,+BAA+B;EAGzC,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,iBAAiB;AACxE,MAAI;AACF,SAAM,MAAM,oBAAoB;IAC9B,QAAQ;IACR;IACA;IACA,QAAQ,WAAW;IACpB,CAAC;YACM;AACR,gBAAa,UAAU;;SAEnB;;AAKV,4BAAe,EAAE,MAAM"}
@@ -0,0 +1,18 @@
1
+ //#region src/telemetry/lambda-client.d.ts
2
+ interface LambdaSendOptions {
3
+ event: string;
4
+ properties?: Record<string, unknown>;
5
+ globalProperties?: Record<string, unknown>;
6
+ packageName?: string;
7
+ packageVersion?: string;
8
+ licenseToken?: string;
9
+ }
10
+ declare function parseTelemetryIdFromLicense(token?: string): string | null;
11
+ declare function parseAndWarnTelemetryId(licenseToken: string): string | null;
12
+ declare function send(opts: LambdaSendOptions): Promise<void>;
13
+ declare const _default: {
14
+ send: typeof send;
15
+ };
16
+ //#endregion
17
+ export { LambdaSendOptions, _default, parseAndWarnTelemetryId, parseTelemetryIdFromLicense };
18
+ //# sourceMappingURL=lambda-client.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambda-client.d.cts","names":[],"sources":["../../src/telemetry/lambda-client.ts"],"mappings":";UAiCiB,iBAAA;EACf,KAAA;EACA,UAAA,GAAa,MAAA;EACb,gBAAA,GAAmB,MAAA;EACnB,WAAA;EACA,cAAA;EAKA,YAAA;AAAA;AAAA,iBAgCc,2BAAA,CAA4B,KAAA;AAAA,iBA0B5B,uBAAA,CAAwB,YAAA;AAAA,iBAUlB,IAAA,CAAK,IAAA,EAAM,iBAAA,GAAoB,OAAA;AAAA,cAuCpD,QAAA"}
@@ -0,0 +1,18 @@
1
+ //#region src/telemetry/lambda-client.d.ts
2
+ interface LambdaSendOptions {
3
+ event: string;
4
+ properties?: Record<string, unknown>;
5
+ globalProperties?: Record<string, unknown>;
6
+ packageName?: string;
7
+ packageVersion?: string;
8
+ licenseToken?: string;
9
+ }
10
+ declare function parseTelemetryIdFromLicense(token?: string): string | null;
11
+ declare function parseAndWarnTelemetryId(licenseToken: string): string | null;
12
+ declare function send(opts: LambdaSendOptions): Promise<void>;
13
+ declare const _default: {
14
+ send: typeof send;
15
+ };
16
+ //#endregion
17
+ export { LambdaSendOptions, _default, parseAndWarnTelemetryId, parseTelemetryIdFromLicense };
18
+ //# sourceMappingURL=lambda-client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambda-client.d.mts","names":[],"sources":["../../src/telemetry/lambda-client.ts"],"mappings":";UAiCiB,iBAAA;EACf,KAAA;EACA,UAAA,GAAa,MAAA;EACb,gBAAA,GAAmB,MAAA;EACnB,WAAA;EACA,cAAA;EAKA,YAAA;AAAA;AAAA,iBAgCc,2BAAA,CAA4B,KAAA;AAAA,iBA0B5B,uBAAA,CAAwB,YAAA;AAAA,iBAUlB,IAAA,CAAK,IAAA,EAAM,iBAAA,GAAoB,OAAA;AAAA,cAuCpD,QAAA"}
@@ -0,0 +1,67 @@
1
+ //#region src/telemetry/lambda-client.ts
2
+ const TELEMETRY_SINK_URL = typeof process !== "undefined" && process.env?.COPILOTKIT_TELEMETRY_URL || "https://telemetry.copilotkit.ai/ingest";
3
+ const FETCH_TIMEOUT_MS = 3e3;
4
+ const STRIPPED_KEYS = new Set(["cloud.public_api_key", "cloud.publicApiKey"]);
5
+ function stripCloudKeys(obj) {
6
+ if (!obj) return {};
7
+ const out = {};
8
+ for (const [k, v] of Object.entries(obj)) if (!STRIPPED_KEYS.has(k)) out[k] = v;
9
+ return out;
10
+ }
11
+ function parseTelemetryIdFromLicense(token) {
12
+ if (!token) return null;
13
+ const parts = token.split(".");
14
+ if (parts.length !== 3) return null;
15
+ try {
16
+ let b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
17
+ const padding = (4 - b64.length % 4) % 4;
18
+ b64 += "=".repeat(padding);
19
+ const json = typeof atob === "function" ? atob(b64) : Buffer.from(b64, "base64").toString("utf8");
20
+ const decoded = JSON.parse(json);
21
+ return typeof decoded.telemetry_id === "string" ? decoded.telemetry_id : null;
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+ function parseAndWarnTelemetryId(licenseToken) {
27
+ const telemetryId = parseTelemetryIdFromLicense(licenseToken);
28
+ if (!telemetryId) console.warn("[CopilotKit] License token did not yield a telemetry_id; telemetry events will be sent anonymously.");
29
+ return telemetryId;
30
+ }
31
+ async function send(opts) {
32
+ try {
33
+ const body = JSON.stringify({
34
+ event: opts.event,
35
+ properties: stripCloudKeys(opts.properties),
36
+ global_properties: stripCloudKeys(opts.globalProperties),
37
+ package: {
38
+ name: opts.packageName,
39
+ version: opts.packageVersion
40
+ },
41
+ ts: Math.floor(Date.now() / 1e3)
42
+ });
43
+ const telemetryId = parseTelemetryIdFromLicense(opts.licenseToken);
44
+ const headers = {
45
+ "Content-Type": "application/json",
46
+ "User-Agent": opts.packageName ? `CopilotKit-Runtime/${opts.packageVersion ?? "unknown"} (${opts.packageName})` : "CopilotKit-Runtime"
47
+ };
48
+ if (telemetryId) headers["X-CopilotKit-Telemetry-Id"] = telemetryId;
49
+ const controller = new AbortController();
50
+ const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
51
+ try {
52
+ await fetch(TELEMETRY_SINK_URL, {
53
+ method: "POST",
54
+ headers,
55
+ body,
56
+ signal: controller.signal
57
+ });
58
+ } finally {
59
+ clearTimeout(timeoutId);
60
+ }
61
+ } catch {}
62
+ }
63
+ var lambda_client_default = { send };
64
+
65
+ //#endregion
66
+ export { lambda_client_default as default, parseAndWarnTelemetryId, parseTelemetryIdFromLicense };
67
+ //# sourceMappingURL=lambda-client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambda-client.mjs","names":[],"sources":["../../src/telemetry/lambda-client.ts"],"sourcesContent":["// Telemetry sink client.\n//\n// Posts events to a CopilotKit-controlled telemetry-sink endpoint, which\n// fans out to Scarf, Reo, and any future destinations. Replaces the direct\n// per-vendor calls (scarf-client.ts) so that vendor changes don't require\n// SDK releases and so that downstream services we don't want exposed to\n// OSS readers (e.g. the email-enrichment service backing Reo) stay\n// private.\n//\n// Two attribution modes:\n// - Identified: a CopilotKit license token is configured. The token is\n// a JWT (header.payload.sig) whose payload carries `telemetry_id`.\n// The SDK base64url-decodes the payload — without verifying the\n// Ed25519 signature, which is the license-verifier's job — and\n// emits the id via `X-CopilotKit-Telemetry-Id`. The Lambda uses it\n// to enrich events with the customer's email.\n// - Anonymous: no license token, or a malformed/non-JWT one. No\n// telemetry-id header; events still flow, attribution is best-effort\n// from request-level signals (IP, UA).\n//\n// Note: CopilotCloud customer API keys (`ck_<env>_<id>.<secret>`) are\n// unrelated to telemetry attribution. They flow into Segment / PostHog\n// via the v1 shared TelemetryClient and never reach this code path.\n//\n// Best-effort: every error is swallowed. Telemetry must not break the\n// host application.\n\nconst TELEMETRY_SINK_URL =\n (typeof process !== \"undefined\" && process.env?.COPILOTKIT_TELEMETRY_URL) ||\n \"https://telemetry.copilotkit.ai/ingest\";\n\nconst FETCH_TIMEOUT_MS = 3000;\n\nexport interface LambdaSendOptions {\n event: string;\n properties?: Record<string, unknown>;\n globalProperties?: Record<string, unknown>;\n packageName?: string;\n packageVersion?: string;\n // The CopilotKit license token (Ed25519-signed JWT), when one is\n // configured on the runtime. The sender base64url-decodes the payload\n // segment to extract `telemetry_id`; missing or malformed tokens\n // produce an anonymous send.\n licenseToken?: string;\n}\n\n// These fields aren't used by the telemetry service, so we strip them\n// at the wire boundary rather than rely on every caller to omit them.\n// Both the snake_case and camelCase variants are listed because callers\n// upstream use different conventions.\nconst STRIPPED_KEYS = new Set([\"cloud.public_api_key\", \"cloud.publicApiKey\"]);\n\nfunction stripCloudKeys(\n obj: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n if (!obj) return {};\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (!STRIPPED_KEYS.has(k)) out[k] = v;\n }\n return out;\n}\n\n// Pull telemetry_id out of a CopilotKit license token without verifying\n// the signature. The token shape is a standard JWT\n// (`<header>.<payload>.<sig>`) with base64url-encoded segments; the\n// payload is JSON with a `telemetry_id` string field.\n//\n// Verification (Ed25519, key rotation, expiry) is the license-verifier\n// package's job. For telemetry attribution we only need the claimed id —\n// the trust model is claim-only on the Lambda side anyway.\n//\n// Exported so TelemetryClient setters can detect unparseable tokens at\n// configuration time and surface a single warning, instead of silently\n// emitting anonymous events on every capture.\nexport function parseTelemetryIdFromLicense(token?: string): string | null {\n if (!token) return null;\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n try {\n let b64 = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = (4 - (b64.length % 4)) % 4;\n b64 += \"=\".repeat(padding);\n const json =\n typeof atob === \"function\"\n ? atob(b64)\n : Buffer.from(b64, \"base64\").toString(\"utf8\");\n const decoded = JSON.parse(json) as { telemetry_id?: unknown };\n return typeof decoded.telemetry_id === \"string\"\n ? decoded.telemetry_id\n : null;\n } catch {\n return null;\n }\n}\n\n// Parse the telemetry_id from a license token AND emit the rollout smoke\n// signal if the parse returned null. Returning the parsed id lets callers\n// cache it in one step (avoiding a second parseTelemetryIdFromLicense\n// pass) while keeping the warn text in lockstep between v1 (shared) and\n// v2 (runtime) TelemetryClient.setLicenseToken.\nexport function parseAndWarnTelemetryId(licenseToken: string): string | null {\n const telemetryId = parseTelemetryIdFromLicense(licenseToken);\n if (!telemetryId) {\n console.warn(\n \"[CopilotKit] License token did not yield a telemetry_id; telemetry events will be sent anonymously.\",\n );\n }\n return telemetryId;\n}\n\nexport async function send(opts: LambdaSendOptions): Promise<void> {\n try {\n const body = JSON.stringify({\n event: opts.event,\n properties: stripCloudKeys(opts.properties),\n global_properties: stripCloudKeys(opts.globalProperties),\n package: {\n name: opts.packageName,\n version: opts.packageVersion,\n },\n ts: Math.floor(Date.now() / 1000),\n });\n\n const telemetryId = parseTelemetryIdFromLicense(opts.licenseToken);\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"User-Agent\": opts.packageName\n ? `CopilotKit-Runtime/${opts.packageVersion ?? \"unknown\"} (${opts.packageName})`\n : \"CopilotKit-Runtime\",\n };\n if (telemetryId) {\n headers[\"X-CopilotKit-Telemetry-Id\"] = telemetryId;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n try {\n await fetch(TELEMETRY_SINK_URL, {\n method: \"POST\",\n headers,\n body,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n } catch {\n // Silent failure — telemetry must not break the application.\n }\n}\n\nexport default { send };\n"],"mappings":";AA2BA,MAAM,qBACH,OAAO,YAAY,eAAe,QAAQ,KAAK,4BAChD;AAEF,MAAM,mBAAmB;AAmBzB,MAAM,gBAAgB,IAAI,IAAI,CAAC,wBAAwB,qBAAqB,CAAC;AAE7E,SAAS,eACP,KACyB;AACzB,KAAI,CAAC,IAAK,QAAO,EAAE;CACnB,MAAM,MAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI,CACtC,KAAI,CAAC,cAAc,IAAI,EAAE,CAAE,KAAI,KAAK;AAEtC,QAAO;;AAeT,SAAgB,4BAA4B,OAA+B;AACzE,KAAI,CAAC,MAAO,QAAO;CACnB,MAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,KAAI;EACF,IAAI,MAAM,MAAM,GAAG,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI;EACxD,MAAM,WAAW,IAAK,IAAI,SAAS,KAAM;AACzC,SAAO,IAAI,OAAO,QAAQ;EAC1B,MAAM,OACJ,OAAO,SAAS,aACZ,KAAK,IAAI,GACT,OAAO,KAAK,KAAK,SAAS,CAAC,SAAS,OAAO;EACjD,MAAM,UAAU,KAAK,MAAM,KAAK;AAChC,SAAO,OAAO,QAAQ,iBAAiB,WACnC,QAAQ,eACR;SACE;AACN,SAAO;;;AASX,SAAgB,wBAAwB,cAAqC;CAC3E,MAAM,cAAc,4BAA4B,aAAa;AAC7D,KAAI,CAAC,YACH,SAAQ,KACN,sGACD;AAEH,QAAO;;AAGT,eAAsB,KAAK,MAAwC;AACjE,KAAI;EACF,MAAM,OAAO,KAAK,UAAU;GAC1B,OAAO,KAAK;GACZ,YAAY,eAAe,KAAK,WAAW;GAC3C,mBAAmB,eAAe,KAAK,iBAAiB;GACxD,SAAS;IACP,MAAM,KAAK;IACX,SAAS,KAAK;IACf;GACD,IAAI,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAClC,CAAC;EAEF,MAAM,cAAc,4BAA4B,KAAK,aAAa;EAClE,MAAM,UAAkC;GACtC,gBAAgB;GAChB,cAAc,KAAK,cACf,sBAAsB,KAAK,kBAAkB,UAAU,IAAI,KAAK,YAAY,KAC5E;GACL;AACD,MAAI,YACF,SAAQ,+BAA+B;EAGzC,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,iBAAiB;AACxE,MAAI;AACF,SAAM,MAAM,oBAAoB;IAC9B,QAAQ;IACR;IACA;IACA,QAAQ,WAAW;IACpB,CAAC;YACM;AACR,gBAAa,UAAU;;SAEnB;;AAKV,4BAAe,EAAE,MAAM"}
@@ -1,6 +1,6 @@
1
1
  const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
2
2
  const require_utils = require('./utils.cjs');
3
- const require_scarf_client = require('./scarf-client.cjs');
3
+ const require_lambda_client = require('./lambda-client.cjs');
4
4
  let uuid = require("uuid");
5
5
  let _segment_analytics_node = require("@segment/analytics-node");
6
6
 
@@ -18,6 +18,8 @@ var TelemetryClient = class {
18
18
  constructor({ packageName, packageVersion, telemetryDisabled, telemetryBaseUrl, sampleRate }) {
19
19
  this.globalProperties = {};
20
20
  this.cloudConfiguration = null;
21
+ this.licenseToken = null;
22
+ this.telemetryId = null;
21
23
  this.telemetryDisabled = false;
22
24
  this.sampleRate = .05;
23
25
  this.anonymousId = `anon_${(0, uuid.v4)()}`;
@@ -36,22 +38,40 @@ var TelemetryClient = class {
36
38
  return Math.random() < this.sampleRate;
37
39
  }
38
40
  async capture(event, properties) {
39
- if (!this.shouldSendEvent() || !this.segment) return;
41
+ if (this.telemetryDisabled) return;
42
+ if (!this.telemetryId && !this.shouldSendEvent()) return;
43
+ const effectiveSampleRate = this.telemetryId ? 1 : this.sampleRate;
44
+ const samplingMeta = {
45
+ sampleRate: effectiveSampleRate,
46
+ sampleRateAdjustmentFactor: 1 - effectiveSampleRate,
47
+ sampleWeight: 1 / effectiveSampleRate
48
+ };
40
49
  const flattenedProperties = require_utils.flattenObject(properties);
41
50
  const propertiesWithGlobal = {
42
51
  ...this.globalProperties,
52
+ ...samplingMeta,
43
53
  ...flattenedProperties
44
54
  };
45
55
  const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal).sort().reduce((obj, key) => {
46
56
  obj[key] = propertiesWithGlobal[key];
47
57
  return obj;
48
58
  }, {});
49
- this.segment.track({
59
+ await require_lambda_client.default.send({
60
+ event,
61
+ properties: flattenedProperties,
62
+ globalProperties: {
63
+ ...this.globalProperties,
64
+ ...samplingMeta
65
+ },
66
+ packageName: this.packageName,
67
+ packageVersion: this.packageVersion,
68
+ licenseToken: this.licenseToken ?? void 0
69
+ });
70
+ if (this.segment) this.segment.track({
50
71
  anonymousId: this.anonymousId,
51
72
  event,
52
73
  properties: { ...orderedPropertiesWithGlobal }
53
74
  });
54
- await require_scarf_client.default.logEvent({ event });
55
75
  }
56
76
  setGlobalProperties(properties) {
57
77
  const flattenedProperties = require_utils.flattenObject(properties);
@@ -67,17 +87,16 @@ var TelemetryClient = class {
67
87
  baseUrl: properties.baseUrl
68
88
  } });
69
89
  }
90
+ setLicenseToken(licenseToken) {
91
+ this.licenseToken = licenseToken;
92
+ this.telemetryId = require_lambda_client.parseAndWarnTelemetryId(licenseToken);
93
+ }
70
94
  setSampleRate(sampleRate) {
71
95
  let _sampleRate;
72
96
  _sampleRate = sampleRate ?? .05;
73
97
  if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);
74
- if (_sampleRate < 0 || _sampleRate > 1) throw new Error("Sample rate must be between 0 and 1");
98
+ if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) throw new Error("Sample rate must be between 0 and 1");
75
99
  this.sampleRate = _sampleRate;
76
- this.setGlobalProperties({
77
- sampleRate: this.sampleRate,
78
- sampleRateAdjustmentFactor: 1 - this.sampleRate,
79
- sampleWeight: 1 / this.sampleRate
80
- });
81
100
  }
82
101
  };
83
102
 
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.cjs","names":["Analytics","flattenObject","scarfClient"],"sources":["../../src/telemetry/telemetry-client.ts"],"sourcesContent":["import { Analytics } from \"@segment/analytics-node\";\nimport { AnalyticsEvents } from \"./events\";\nimport { flattenObject } from \"./utils\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport scarfClient from \"./scarf-client\";\n\n/**\n * Checks if telemetry is disabled via environment variables.\n * Users can opt out by setting:\n * - COPILOTKIT_TELEMETRY_DISABLED=true or COPILOTKIT_TELEMETRY_DISABLED=1\n * - DO_NOT_TRACK=true or DO_NOT_TRACK=1\n */\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n segment: Analytics | undefined;\n globalProperties: Record<string, any> = {};\n cloudConfiguration: { publicApiKey: string; baseUrl: string } | null = null;\n packageName: string;\n packageVersion: string;\n private telemetryDisabled: boolean = false;\n private sampleRate: number = 0.05;\n private anonymousId = `anon_${uuidv4()}`;\n\n constructor({\n packageName,\n packageVersion,\n telemetryDisabled,\n telemetryBaseUrl,\n sampleRate,\n }: {\n packageName: string;\n packageVersion: string;\n telemetryDisabled?: boolean;\n telemetryBaseUrl?: string;\n sampleRate?: number;\n }) {\n this.packageName = packageName;\n this.packageVersion = packageVersion;\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n\n if (this.telemetryDisabled) {\n return;\n }\n\n this.setSampleRate(sampleRate);\n\n // eslint-disable-next-line\n const writeKey =\n process.env.COPILOTKIT_SEGMENT_WRITE_KEY ||\n \"n7XAZtQCGS2v1vvBy3LgBCv2h3Y8whja\";\n\n this.segment = new Analytics({\n writeKey,\n });\n\n this.setGlobalProperties({\n \"copilotkit.package.name\": packageName,\n \"copilotkit.package.version\": packageVersion,\n });\n }\n\n private shouldSendEvent() {\n const randomNumber = Math.random();\n return randomNumber < this.sampleRate;\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (!this.shouldSendEvent() || !this.segment) {\n return;\n }\n\n const flattenedProperties = flattenObject(properties);\n const propertiesWithGlobal = {\n ...this.globalProperties,\n ...flattenedProperties,\n };\n const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal)\n .sort()\n .reduce(\n (obj, key) => {\n obj[key] = propertiesWithGlobal[key];\n return obj;\n },\n {} as Record<string, any>,\n );\n\n this.segment.track({\n anonymousId: this.anonymousId,\n event,\n properties: { ...orderedPropertiesWithGlobal },\n });\n\n await scarfClient.logEvent({\n event,\n });\n }\n\n setGlobalProperties(properties: Record<string, any>) {\n const flattenedProperties = flattenObject(properties);\n this.globalProperties = {\n ...this.globalProperties,\n ...flattenedProperties,\n };\n }\n\n setCloudConfiguration(properties: { publicApiKey: string; baseUrl: string }) {\n this.cloudConfiguration = properties;\n\n this.setGlobalProperties({\n cloud: {\n publicApiKey: properties.publicApiKey,\n baseUrl: properties.baseUrl,\n },\n });\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n // eslint-disable-next-line\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n // eslint-disable-next-line\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n if (_sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n this.setGlobalProperties({\n sampleRate: this.sampleRate,\n sampleRateAdjustmentFactor: 1 - this.sampleRate,\n sampleWeight: 1 / this.sampleRate,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAU3B,YAAY,EACV,aACA,gBACA,mBACA,kBACA,cAOC;0BApBqC,EAAE;4BAC6B;2BAGlC;oBACR;qBACP,sBAAgB;AAepC,OAAK,cAAc;AACnB,OAAK,iBAAiB;AACtB,OAAK,oBAAoB,qBAAqB,qBAAqB;AAEnE,MAAI,KAAK,kBACP;AAGF,OAAK,cAAc,WAAW;AAO9B,OAAK,UAAU,IAAIA,kCAAU,EAC3B,UAJA,QAAQ,IAAI,gCACZ,oCAID,CAAC;AAEF,OAAK,oBAAoB;GACvB,2BAA2B;GAC3B,8BAA8B;GAC/B,CAAC;;CAGJ,AAAQ,kBAAkB;AAExB,SADqB,KAAK,QAAQ,GACZ,KAAK;;CAG7B,MAAM,QACJ,OACA,YACA;AACA,MAAI,CAAC,KAAK,iBAAiB,IAAI,CAAC,KAAK,QACnC;EAGF,MAAM,sBAAsBC,4BAAc,WAAW;EACrD,MAAM,uBAAuB;GAC3B,GAAG,KAAK;GACR,GAAG;GACJ;EACD,MAAM,8BAA8B,OAAO,KAAK,qBAAqB,CAClE,MAAM,CACN,QACE,KAAK,QAAQ;AACZ,OAAI,OAAO,qBAAqB;AAChC,UAAO;KAET,EAAE,CACH;AAEH,OAAK,QAAQ,MAAM;GACjB,aAAa,KAAK;GAClB;GACA,YAAY,EAAE,GAAG,6BAA6B;GAC/C,CAAC;AAEF,QAAMC,6BAAY,SAAS,EACzB,OACD,CAAC;;CAGJ,oBAAoB,YAAiC;EACnD,MAAM,sBAAsBD,4BAAc,WAAW;AACrD,OAAK,mBAAmB;GACtB,GAAG,KAAK;GACR,GAAG;GACJ;;CAGH,sBAAsB,YAAuD;AAC3E,OAAK,qBAAqB;AAE1B,OAAK,oBAAoB,EACvB,OAAO;GACL,cAAc,WAAW;GACzB,SAAS,WAAW;GACrB,EACF,CAAC;;CAGJ,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAG5B,MAAI,QAAQ,IAAI,iCAEd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAGxE,MAAI,cAAc,KAAK,cAAc,EACnC,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;AAClB,OAAK,oBAAoB;GACvB,YAAY,KAAK;GACjB,4BAA4B,IAAI,KAAK;GACrC,cAAc,IAAI,KAAK;GACxB,CAAC"}
1
+ {"version":3,"file":"telemetry-client.cjs","names":["Analytics","flattenObject","lambdaClient","parseAndWarnTelemetryId"],"sources":["../../src/telemetry/telemetry-client.ts"],"sourcesContent":["import { Analytics } from \"@segment/analytics-node\";\nimport type { AnalyticsEvents } from \"./events\";\nimport { flattenObject } from \"./utils\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport lambdaClient, { parseAndWarnTelemetryId } from \"./lambda-client\";\n\n/**\n * Checks if telemetry is disabled via environment variables.\n * Users can opt out by setting:\n * - COPILOTKIT_TELEMETRY_DISABLED=true or COPILOTKIT_TELEMETRY_DISABLED=1\n * - DO_NOT_TRACK=true or DO_NOT_TRACK=1\n */\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n segment: Analytics | undefined;\n globalProperties: Record<string, any> = {};\n cloudConfiguration: { publicApiKey: string; baseUrl: string } | null = null;\n // EIP / Intelligence license token (Ed25519-signed JWT). The lambda\n // client decodes its payload to extract telemetry_id. Customer API\n // keys are NOT used here — they flow only into Segment.\n private licenseToken: string | null = null;\n // Parsed telemetry_id from the license-token JWT payload. Cached at\n // setLicenseToken time so `capture()` can branch on identified vs\n // anonymous without re-parsing per event. Null when the token is\n // absent or yielded no telemetry_id.\n private telemetryId: string | null = null;\n packageName: string;\n packageVersion: string;\n private telemetryDisabled: boolean = false;\n // Client-side sampling rate for anonymous events. Identified events\n // (those whose license token yielded a telemetry_id) bypass the gate\n // entirely. Applied uniformly to both the lambda sink and Segment —\n // one dice roll per capture, both sinks see the same decision.\n private sampleRate: number = 0.05;\n private anonymousId = `anon_${uuidv4()}`;\n\n constructor({\n packageName,\n packageVersion,\n telemetryDisabled,\n telemetryBaseUrl,\n sampleRate,\n }: {\n packageName: string;\n packageVersion: string;\n telemetryDisabled?: boolean;\n telemetryBaseUrl?: string;\n sampleRate?: number;\n }) {\n this.packageName = packageName;\n this.packageVersion = packageVersion;\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n\n if (this.telemetryDisabled) {\n return;\n }\n\n this.setSampleRate(sampleRate);\n\n // eslint-disable-next-line\n const writeKey =\n process.env.COPILOTKIT_SEGMENT_WRITE_KEY ||\n \"n7XAZtQCGS2v1vvBy3LgBCv2h3Y8whja\";\n\n this.segment = new Analytics({\n writeKey,\n });\n\n this.setGlobalProperties({\n \"copilotkit.package.name\": packageName,\n \"copilotkit.package.version\": packageVersion,\n });\n }\n\n private shouldSendEvent() {\n const randomNumber = Math.random();\n return randomNumber < this.sampleRate;\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (this.telemetryDisabled) {\n return;\n }\n\n // Anonymous callers (no telemetry_id) are gated by sampleRate.\n // Identified callers (license token with telemetry_id) always send —\n // the volume is bounded by paying-customer count and full fidelity\n // per identified customer is worth the marginal cost.\n if (!this.telemetryId && !this.shouldSendEvent()) {\n return;\n }\n\n // Identified events ship at 100% effective rate, anonymous events at\n // sampleRate. Compute per-event so downstream weight-based extrapolation\n // (sampleWeight = 1 / effectiveRate) is correct for both populations;\n // a single global sampleWeight would overweight identified-customer\n // counts by 1/sampleRate.\n const effectiveSampleRate = this.telemetryId ? 1 : this.sampleRate;\n const samplingMeta = {\n sampleRate: effectiveSampleRate,\n sampleRateAdjustmentFactor: 1 - effectiveSampleRate,\n sampleWeight: 1 / effectiveSampleRate,\n };\n\n const flattenedProperties = flattenObject(properties);\n const propertiesWithGlobal = {\n ...this.globalProperties,\n ...samplingMeta,\n ...flattenedProperties,\n };\n const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal)\n .sort()\n .reduce(\n (obj, key) => {\n obj[key] = propertiesWithGlobal[key];\n return obj;\n },\n {} as Record<string, any>,\n );\n\n await lambdaClient.send({\n event,\n properties: flattenedProperties,\n globalProperties: { ...this.globalProperties, ...samplingMeta },\n packageName: this.packageName,\n packageVersion: this.packageVersion,\n licenseToken: this.licenseToken ?? undefined,\n });\n\n if (this.segment) {\n this.segment.track({\n anonymousId: this.anonymousId,\n event,\n properties: { ...orderedPropertiesWithGlobal },\n });\n }\n }\n\n setGlobalProperties(properties: Record<string, any>) {\n const flattenedProperties = flattenObject(properties);\n this.globalProperties = {\n ...this.globalProperties,\n ...flattenedProperties,\n };\n }\n\n setCloudConfiguration(properties: { publicApiKey: string; baseUrl: string }) {\n this.cloudConfiguration = properties;\n\n this.setGlobalProperties({\n cloud: {\n publicApiKey: properties.publicApiKey,\n baseUrl: properties.baseUrl,\n },\n });\n }\n\n // The license token isn't added to globalProperties — we don't want\n // the JWT itself shipped on every event. Only its decoded telemetry_id\n // travels, in the X-CopilotKit-Telemetry-Id header set by lambda-client.\n setLicenseToken(licenseToken: string) {\n this.licenseToken = licenseToken;\n this.telemetryId = parseAndWarnTelemetryId(licenseToken);\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n // eslint-disable-next-line\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n // eslint-disable-next-line\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n // Number.isNaN guards against parseFloat(\"nonsense\") slipping past the\n // range check (all NaN comparisons are false), which would silently\n // drop every anonymous event with no signal — especially important\n // since the default is now 0.05, making env-var overrides more common.\n if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n // Per-event sampling metadata (sampleRate/sampleRateAdjustmentFactor/\n // sampleWeight) is computed in capture() so identified events get\n // their own effectiveSampleRate=1 weight instead of the anonymous\n // population's 1/sampleRate.\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAuB3B,YAAY,EACV,aACA,gBACA,mBACA,kBACA,cAOC;0BAjCqC,EAAE;4BAC6B;sBAIjC;qBAKD;2BAGA;oBAKR;qBACP,sBAAgB;AAepC,OAAK,cAAc;AACnB,OAAK,iBAAiB;AACtB,OAAK,oBAAoB,qBAAqB,qBAAqB;AAEnE,MAAI,KAAK,kBACP;AAGF,OAAK,cAAc,WAAW;AAO9B,OAAK,UAAU,IAAIA,kCAAU,EAC3B,UAJA,QAAQ,IAAI,gCACZ,oCAID,CAAC;AAEF,OAAK,oBAAoB;GACvB,2BAA2B;GAC3B,8BAA8B;GAC/B,CAAC;;CAGJ,AAAQ,kBAAkB;AAExB,SADqB,KAAK,QAAQ,GACZ,KAAK;;CAG7B,MAAM,QACJ,OACA,YACA;AACA,MAAI,KAAK,kBACP;AAOF,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,iBAAiB,CAC9C;EAQF,MAAM,sBAAsB,KAAK,cAAc,IAAI,KAAK;EACxD,MAAM,eAAe;GACnB,YAAY;GACZ,4BAA4B,IAAI;GAChC,cAAc,IAAI;GACnB;EAED,MAAM,sBAAsBC,4BAAc,WAAW;EACrD,MAAM,uBAAuB;GAC3B,GAAG,KAAK;GACR,GAAG;GACH,GAAG;GACJ;EACD,MAAM,8BAA8B,OAAO,KAAK,qBAAqB,CAClE,MAAM,CACN,QACE,KAAK,QAAQ;AACZ,OAAI,OAAO,qBAAqB;AAChC,UAAO;KAET,EAAE,CACH;AAEH,QAAMC,8BAAa,KAAK;GACtB;GACA,YAAY;GACZ,kBAAkB;IAAE,GAAG,KAAK;IAAkB,GAAG;IAAc;GAC/D,aAAa,KAAK;GAClB,gBAAgB,KAAK;GACrB,cAAc,KAAK,gBAAgB;GACpC,CAAC;AAEF,MAAI,KAAK,QACP,MAAK,QAAQ,MAAM;GACjB,aAAa,KAAK;GAClB;GACA,YAAY,EAAE,GAAG,6BAA6B;GAC/C,CAAC;;CAIN,oBAAoB,YAAiC;EACnD,MAAM,sBAAsBD,4BAAc,WAAW;AACrD,OAAK,mBAAmB;GACtB,GAAG,KAAK;GACR,GAAG;GACJ;;CAGH,sBAAsB,YAAuD;AAC3E,OAAK,qBAAqB;AAE1B,OAAK,oBAAoB,EACvB,OAAO;GACL,cAAc,WAAW;GACzB,SAAS,WAAW;GACrB,EACF,CAAC;;CAMJ,gBAAgB,cAAsB;AACpC,OAAK,eAAe;AACpB,OAAK,cAAcE,8CAAwB,aAAa;;CAG1D,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAG5B,MAAI,QAAQ,IAAI,iCAEd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAOxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa"}
@@ -16,6 +16,8 @@ declare class TelemetryClient {
16
16
  publicApiKey: string;
17
17
  baseUrl: string;
18
18
  } | null;
19
+ private licenseToken;
20
+ private telemetryId;
19
21
  packageName: string;
20
22
  packageVersion: string;
21
23
  private telemetryDisabled;
@@ -41,6 +43,7 @@ declare class TelemetryClient {
41
43
  publicApiKey: string;
42
44
  baseUrl: string;
43
45
  }): void;
46
+ setLicenseToken(licenseToken: string): void;
44
47
  private setSampleRate;
45
48
  }
46
49
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.d.cts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;AAYA;;;;iBAAgB,mBAAA,CAAA;AAAA,cAYH,eAAA;EACX,OAAA,EAAS,SAAA;EACT,gBAAA,EAAkB,MAAA;EAClB,kBAAA;IAAsB,YAAA;IAAsB,OAAA;EAAA;EAC5C,WAAA;EACA,cAAA;EAAA,QACQ,iBAAA;EAAA,QACA,UAAA;EAAA,QACA,WAAA;;IAGN,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA;EAAA;IAEA,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA,UAAA;EAAA;EAAA,QA2BM,eAAA;EAKF,OAAA,iBAAwB,eAAA,CAAA,CAC5B,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAAE,OAAA;EAgChC,mBAAA,CAAoB,UAAA,EAAY,MAAA;EAQhC,qBAAA,CAAsB,UAAA;IAAc,YAAA;IAAsB,OAAA;EAAA;EAAA,QAWlD,aAAA;AAAA"}
1
+ {"version":3,"file":"telemetry-client.d.cts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;AAYA;;;;iBAAgB,mBAAA,CAAA;AAAA,cAYH,eAAA;EACX,OAAA,EAAS,SAAA;EACT,gBAAA,EAAkB,MAAA;EAClB,kBAAA;IAAsB,YAAA;IAAsB,OAAA;EAAA;EAAA,QAIpC,YAAA;EAAA,QAKA,WAAA;EACR,WAAA;EACA,cAAA;EAAA,QACQ,iBAAA;EAAA,QAKA,UAAA;EAAA,QACA,WAAA;;IAGN,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA;EAAA;IAEA,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA,UAAA;EAAA;EAAA,QA2BM,eAAA;EAKF,OAAA,iBAAwB,eAAA,CAAA,CAC5B,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAAE,OAAA;EA4DhC,mBAAA,CAAoB,UAAA,EAAY,MAAA;EAQhC,qBAAA,CAAsB,UAAA;IAAc,YAAA;IAAsB,OAAA;EAAA;EAc1D,eAAA,CAAgB,YAAA;EAAA,QAKR,aAAA;AAAA"}
@@ -16,6 +16,8 @@ declare class TelemetryClient {
16
16
  publicApiKey: string;
17
17
  baseUrl: string;
18
18
  } | null;
19
+ private licenseToken;
20
+ private telemetryId;
19
21
  packageName: string;
20
22
  packageVersion: string;
21
23
  private telemetryDisabled;
@@ -41,6 +43,7 @@ declare class TelemetryClient {
41
43
  publicApiKey: string;
42
44
  baseUrl: string;
43
45
  }): void;
46
+ setLicenseToken(licenseToken: string): void;
44
47
  private setSampleRate;
45
48
  }
46
49
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.d.mts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;AAYA;;;;iBAAgB,mBAAA,CAAA;AAAA,cAYH,eAAA;EACX,OAAA,EAAS,SAAA;EACT,gBAAA,EAAkB,MAAA;EAClB,kBAAA;IAAsB,YAAA;IAAsB,OAAA;EAAA;EAC5C,WAAA;EACA,cAAA;EAAA,QACQ,iBAAA;EAAA,QACA,UAAA;EAAA,QACA,WAAA;;IAGN,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA;EAAA;IAEA,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA,UAAA;EAAA;EAAA,QA2BM,eAAA;EAKF,OAAA,iBAAwB,eAAA,CAAA,CAC5B,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAAE,OAAA;EAgChC,mBAAA,CAAoB,UAAA,EAAY,MAAA;EAQhC,qBAAA,CAAsB,UAAA;IAAc,YAAA;IAAsB,OAAA;EAAA;EAAA,QAWlD,aAAA;AAAA"}
1
+ {"version":3,"file":"telemetry-client.d.mts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;AAYA;;;;iBAAgB,mBAAA,CAAA;AAAA,cAYH,eAAA;EACX,OAAA,EAAS,SAAA;EACT,gBAAA,EAAkB,MAAA;EAClB,kBAAA;IAAsB,YAAA;IAAsB,OAAA;EAAA;EAAA,QAIpC,YAAA;EAAA,QAKA,WAAA;EACR,WAAA;EACA,cAAA;EAAA,QACQ,iBAAA;EAAA,QAKA,UAAA;EAAA,QACA,WAAA;;IAGN,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA;EAAA;IAEA,WAAA;IACA,cAAA;IACA,iBAAA;IACA,gBAAA;IACA,UAAA;EAAA;EAAA,QA2BM,eAAA;EAKF,OAAA,iBAAwB,eAAA,CAAA,CAC5B,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAAE,OAAA;EA4DhC,mBAAA,CAAoB,UAAA,EAAY,MAAA;EAQhC,qBAAA,CAAsB,UAAA;IAAc,YAAA;IAAsB,OAAA;EAAA;EAc1D,eAAA,CAAgB,YAAA;EAAA,QAKR,aAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
  import { flattenObject } from "./utils.mjs";
2
- import scarf_client_default from "./scarf-client.mjs";
2
+ import lambda_client_default, { parseAndWarnTelemetryId } from "./lambda-client.mjs";
3
3
  import { v4 } from "uuid";
4
4
  import { Analytics } from "@segment/analytics-node";
5
5
 
@@ -17,6 +17,8 @@ var TelemetryClient = class {
17
17
  constructor({ packageName, packageVersion, telemetryDisabled, telemetryBaseUrl, sampleRate }) {
18
18
  this.globalProperties = {};
19
19
  this.cloudConfiguration = null;
20
+ this.licenseToken = null;
21
+ this.telemetryId = null;
20
22
  this.telemetryDisabled = false;
21
23
  this.sampleRate = .05;
22
24
  this.anonymousId = `anon_${v4()}`;
@@ -35,22 +37,40 @@ var TelemetryClient = class {
35
37
  return Math.random() < this.sampleRate;
36
38
  }
37
39
  async capture(event, properties) {
38
- if (!this.shouldSendEvent() || !this.segment) return;
40
+ if (this.telemetryDisabled) return;
41
+ if (!this.telemetryId && !this.shouldSendEvent()) return;
42
+ const effectiveSampleRate = this.telemetryId ? 1 : this.sampleRate;
43
+ const samplingMeta = {
44
+ sampleRate: effectiveSampleRate,
45
+ sampleRateAdjustmentFactor: 1 - effectiveSampleRate,
46
+ sampleWeight: 1 / effectiveSampleRate
47
+ };
39
48
  const flattenedProperties = flattenObject(properties);
40
49
  const propertiesWithGlobal = {
41
50
  ...this.globalProperties,
51
+ ...samplingMeta,
42
52
  ...flattenedProperties
43
53
  };
44
54
  const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal).sort().reduce((obj, key) => {
45
55
  obj[key] = propertiesWithGlobal[key];
46
56
  return obj;
47
57
  }, {});
48
- this.segment.track({
58
+ await lambda_client_default.send({
59
+ event,
60
+ properties: flattenedProperties,
61
+ globalProperties: {
62
+ ...this.globalProperties,
63
+ ...samplingMeta
64
+ },
65
+ packageName: this.packageName,
66
+ packageVersion: this.packageVersion,
67
+ licenseToken: this.licenseToken ?? void 0
68
+ });
69
+ if (this.segment) this.segment.track({
49
70
  anonymousId: this.anonymousId,
50
71
  event,
51
72
  properties: { ...orderedPropertiesWithGlobal }
52
73
  });
53
- await scarf_client_default.logEvent({ event });
54
74
  }
55
75
  setGlobalProperties(properties) {
56
76
  const flattenedProperties = flattenObject(properties);
@@ -66,17 +86,16 @@ var TelemetryClient = class {
66
86
  baseUrl: properties.baseUrl
67
87
  } });
68
88
  }
89
+ setLicenseToken(licenseToken) {
90
+ this.licenseToken = licenseToken;
91
+ this.telemetryId = parseAndWarnTelemetryId(licenseToken);
92
+ }
69
93
  setSampleRate(sampleRate) {
70
94
  let _sampleRate;
71
95
  _sampleRate = sampleRate ?? .05;
72
96
  if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);
73
- if (_sampleRate < 0 || _sampleRate > 1) throw new Error("Sample rate must be between 0 and 1");
97
+ if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) throw new Error("Sample rate must be between 0 and 1");
74
98
  this.sampleRate = _sampleRate;
75
- this.setGlobalProperties({
76
- sampleRate: this.sampleRate,
77
- sampleRateAdjustmentFactor: 1 - this.sampleRate,
78
- sampleWeight: 1 / this.sampleRate
79
- });
80
99
  }
81
100
  };
82
101
 
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.mjs","names":["uuidv4","scarfClient"],"sources":["../../src/telemetry/telemetry-client.ts"],"sourcesContent":["import { Analytics } from \"@segment/analytics-node\";\nimport { AnalyticsEvents } from \"./events\";\nimport { flattenObject } from \"./utils\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport scarfClient from \"./scarf-client\";\n\n/**\n * Checks if telemetry is disabled via environment variables.\n * Users can opt out by setting:\n * - COPILOTKIT_TELEMETRY_DISABLED=true or COPILOTKIT_TELEMETRY_DISABLED=1\n * - DO_NOT_TRACK=true or DO_NOT_TRACK=1\n */\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n segment: Analytics | undefined;\n globalProperties: Record<string, any> = {};\n cloudConfiguration: { publicApiKey: string; baseUrl: string } | null = null;\n packageName: string;\n packageVersion: string;\n private telemetryDisabled: boolean = false;\n private sampleRate: number = 0.05;\n private anonymousId = `anon_${uuidv4()}`;\n\n constructor({\n packageName,\n packageVersion,\n telemetryDisabled,\n telemetryBaseUrl,\n sampleRate,\n }: {\n packageName: string;\n packageVersion: string;\n telemetryDisabled?: boolean;\n telemetryBaseUrl?: string;\n sampleRate?: number;\n }) {\n this.packageName = packageName;\n this.packageVersion = packageVersion;\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n\n if (this.telemetryDisabled) {\n return;\n }\n\n this.setSampleRate(sampleRate);\n\n // eslint-disable-next-line\n const writeKey =\n process.env.COPILOTKIT_SEGMENT_WRITE_KEY ||\n \"n7XAZtQCGS2v1vvBy3LgBCv2h3Y8whja\";\n\n this.segment = new Analytics({\n writeKey,\n });\n\n this.setGlobalProperties({\n \"copilotkit.package.name\": packageName,\n \"copilotkit.package.version\": packageVersion,\n });\n }\n\n private shouldSendEvent() {\n const randomNumber = Math.random();\n return randomNumber < this.sampleRate;\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (!this.shouldSendEvent() || !this.segment) {\n return;\n }\n\n const flattenedProperties = flattenObject(properties);\n const propertiesWithGlobal = {\n ...this.globalProperties,\n ...flattenedProperties,\n };\n const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal)\n .sort()\n .reduce(\n (obj, key) => {\n obj[key] = propertiesWithGlobal[key];\n return obj;\n },\n {} as Record<string, any>,\n );\n\n this.segment.track({\n anonymousId: this.anonymousId,\n event,\n properties: { ...orderedPropertiesWithGlobal },\n });\n\n await scarfClient.logEvent({\n event,\n });\n }\n\n setGlobalProperties(properties: Record<string, any>) {\n const flattenedProperties = flattenObject(properties);\n this.globalProperties = {\n ...this.globalProperties,\n ...flattenedProperties,\n };\n }\n\n setCloudConfiguration(properties: { publicApiKey: string; baseUrl: string }) {\n this.cloudConfiguration = properties;\n\n this.setGlobalProperties({\n cloud: {\n publicApiKey: properties.publicApiKey,\n baseUrl: properties.baseUrl,\n },\n });\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n // eslint-disable-next-line\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n // eslint-disable-next-line\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n if (_sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n this.setGlobalProperties({\n sampleRate: this.sampleRate,\n sampleRateAdjustmentFactor: 1 - this.sampleRate,\n sampleWeight: 1 / this.sampleRate,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAU3B,YAAY,EACV,aACA,gBACA,mBACA,kBACA,cAOC;0BApBqC,EAAE;4BAC6B;2BAGlC;oBACR;qBACP,QAAQA,IAAQ;AAepC,OAAK,cAAc;AACnB,OAAK,iBAAiB;AACtB,OAAK,oBAAoB,qBAAqB,qBAAqB;AAEnE,MAAI,KAAK,kBACP;AAGF,OAAK,cAAc,WAAW;AAO9B,OAAK,UAAU,IAAI,UAAU,EAC3B,UAJA,QAAQ,IAAI,gCACZ,oCAID,CAAC;AAEF,OAAK,oBAAoB;GACvB,2BAA2B;GAC3B,8BAA8B;GAC/B,CAAC;;CAGJ,AAAQ,kBAAkB;AAExB,SADqB,KAAK,QAAQ,GACZ,KAAK;;CAG7B,MAAM,QACJ,OACA,YACA;AACA,MAAI,CAAC,KAAK,iBAAiB,IAAI,CAAC,KAAK,QACnC;EAGF,MAAM,sBAAsB,cAAc,WAAW;EACrD,MAAM,uBAAuB;GAC3B,GAAG,KAAK;GACR,GAAG;GACJ;EACD,MAAM,8BAA8B,OAAO,KAAK,qBAAqB,CAClE,MAAM,CACN,QACE,KAAK,QAAQ;AACZ,OAAI,OAAO,qBAAqB;AAChC,UAAO;KAET,EAAE,CACH;AAEH,OAAK,QAAQ,MAAM;GACjB,aAAa,KAAK;GAClB;GACA,YAAY,EAAE,GAAG,6BAA6B;GAC/C,CAAC;AAEF,QAAMC,qBAAY,SAAS,EACzB,OACD,CAAC;;CAGJ,oBAAoB,YAAiC;EACnD,MAAM,sBAAsB,cAAc,WAAW;AACrD,OAAK,mBAAmB;GACtB,GAAG,KAAK;GACR,GAAG;GACJ;;CAGH,sBAAsB,YAAuD;AAC3E,OAAK,qBAAqB;AAE1B,OAAK,oBAAoB,EACvB,OAAO;GACL,cAAc,WAAW;GACzB,SAAS,WAAW;GACrB,EACF,CAAC;;CAGJ,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAG5B,MAAI,QAAQ,IAAI,iCAEd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAGxE,MAAI,cAAc,KAAK,cAAc,EACnC,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;AAClB,OAAK,oBAAoB;GACvB,YAAY,KAAK;GACjB,4BAA4B,IAAI,KAAK;GACrC,cAAc,IAAI,KAAK;GACxB,CAAC"}
1
+ {"version":3,"file":"telemetry-client.mjs","names":["uuidv4","lambdaClient"],"sources":["../../src/telemetry/telemetry-client.ts"],"sourcesContent":["import { Analytics } from \"@segment/analytics-node\";\nimport type { AnalyticsEvents } from \"./events\";\nimport { flattenObject } from \"./utils\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport lambdaClient, { parseAndWarnTelemetryId } from \"./lambda-client\";\n\n/**\n * Checks if telemetry is disabled via environment variables.\n * Users can opt out by setting:\n * - COPILOTKIT_TELEMETRY_DISABLED=true or COPILOTKIT_TELEMETRY_DISABLED=1\n * - DO_NOT_TRACK=true or DO_NOT_TRACK=1\n */\nexport function isTelemetryDisabled(): boolean {\n return (\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"true\" ||\n (process.env as Record<string, string | undefined>)\n .COPILOTKIT_TELEMETRY_DISABLED === \"1\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK ===\n \"true\" ||\n (process.env as Record<string, string | undefined>).DO_NOT_TRACK === \"1\"\n );\n}\n\nexport class TelemetryClient {\n segment: Analytics | undefined;\n globalProperties: Record<string, any> = {};\n cloudConfiguration: { publicApiKey: string; baseUrl: string } | null = null;\n // EIP / Intelligence license token (Ed25519-signed JWT). The lambda\n // client decodes its payload to extract telemetry_id. Customer API\n // keys are NOT used here — they flow only into Segment.\n private licenseToken: string | null = null;\n // Parsed telemetry_id from the license-token JWT payload. Cached at\n // setLicenseToken time so `capture()` can branch on identified vs\n // anonymous without re-parsing per event. Null when the token is\n // absent or yielded no telemetry_id.\n private telemetryId: string | null = null;\n packageName: string;\n packageVersion: string;\n private telemetryDisabled: boolean = false;\n // Client-side sampling rate for anonymous events. Identified events\n // (those whose license token yielded a telemetry_id) bypass the gate\n // entirely. Applied uniformly to both the lambda sink and Segment —\n // one dice roll per capture, both sinks see the same decision.\n private sampleRate: number = 0.05;\n private anonymousId = `anon_${uuidv4()}`;\n\n constructor({\n packageName,\n packageVersion,\n telemetryDisabled,\n telemetryBaseUrl,\n sampleRate,\n }: {\n packageName: string;\n packageVersion: string;\n telemetryDisabled?: boolean;\n telemetryBaseUrl?: string;\n sampleRate?: number;\n }) {\n this.packageName = packageName;\n this.packageVersion = packageVersion;\n this.telemetryDisabled = telemetryDisabled || isTelemetryDisabled();\n\n if (this.telemetryDisabled) {\n return;\n }\n\n this.setSampleRate(sampleRate);\n\n // eslint-disable-next-line\n const writeKey =\n process.env.COPILOTKIT_SEGMENT_WRITE_KEY ||\n \"n7XAZtQCGS2v1vvBy3LgBCv2h3Y8whja\";\n\n this.segment = new Analytics({\n writeKey,\n });\n\n this.setGlobalProperties({\n \"copilotkit.package.name\": packageName,\n \"copilotkit.package.version\": packageVersion,\n });\n }\n\n private shouldSendEvent() {\n const randomNumber = Math.random();\n return randomNumber < this.sampleRate;\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (this.telemetryDisabled) {\n return;\n }\n\n // Anonymous callers (no telemetry_id) are gated by sampleRate.\n // Identified callers (license token with telemetry_id) always send —\n // the volume is bounded by paying-customer count and full fidelity\n // per identified customer is worth the marginal cost.\n if (!this.telemetryId && !this.shouldSendEvent()) {\n return;\n }\n\n // Identified events ship at 100% effective rate, anonymous events at\n // sampleRate. Compute per-event so downstream weight-based extrapolation\n // (sampleWeight = 1 / effectiveRate) is correct for both populations;\n // a single global sampleWeight would overweight identified-customer\n // counts by 1/sampleRate.\n const effectiveSampleRate = this.telemetryId ? 1 : this.sampleRate;\n const samplingMeta = {\n sampleRate: effectiveSampleRate,\n sampleRateAdjustmentFactor: 1 - effectiveSampleRate,\n sampleWeight: 1 / effectiveSampleRate,\n };\n\n const flattenedProperties = flattenObject(properties);\n const propertiesWithGlobal = {\n ...this.globalProperties,\n ...samplingMeta,\n ...flattenedProperties,\n };\n const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal)\n .sort()\n .reduce(\n (obj, key) => {\n obj[key] = propertiesWithGlobal[key];\n return obj;\n },\n {} as Record<string, any>,\n );\n\n await lambdaClient.send({\n event,\n properties: flattenedProperties,\n globalProperties: { ...this.globalProperties, ...samplingMeta },\n packageName: this.packageName,\n packageVersion: this.packageVersion,\n licenseToken: this.licenseToken ?? undefined,\n });\n\n if (this.segment) {\n this.segment.track({\n anonymousId: this.anonymousId,\n event,\n properties: { ...orderedPropertiesWithGlobal },\n });\n }\n }\n\n setGlobalProperties(properties: Record<string, any>) {\n const flattenedProperties = flattenObject(properties);\n this.globalProperties = {\n ...this.globalProperties,\n ...flattenedProperties,\n };\n }\n\n setCloudConfiguration(properties: { publicApiKey: string; baseUrl: string }) {\n this.cloudConfiguration = properties;\n\n this.setGlobalProperties({\n cloud: {\n publicApiKey: properties.publicApiKey,\n baseUrl: properties.baseUrl,\n },\n });\n }\n\n // The license token isn't added to globalProperties — we don't want\n // the JWT itself shipped on every event. Only its decoded telemetry_id\n // travels, in the X-CopilotKit-Telemetry-Id header set by lambda-client.\n setLicenseToken(licenseToken: string) {\n this.licenseToken = licenseToken;\n this.telemetryId = parseAndWarnTelemetryId(licenseToken);\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n // eslint-disable-next-line\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\n // eslint-disable-next-line\n _sampleRate = parseFloat(process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE);\n }\n\n // Number.isNaN guards against parseFloat(\"nonsense\") slipping past the\n // range check (all NaN comparisons are false), which would silently\n // drop every anonymous event with no signal — especially important\n // since the default is now 0.05, making env-var overrides more common.\n if (Number.isNaN(_sampleRate) || _sampleRate < 0 || _sampleRate > 1) {\n throw new Error(\"Sample rate must be between 0 and 1\");\n }\n\n this.sampleRate = _sampleRate;\n // Per-event sampling metadata (sampleRate/sampleRateAdjustmentFactor/\n // sampleWeight) is computed in capture() so identified events get\n // their own effectiveSampleRate=1 weight instead of the anonymous\n // population's 1/sampleRate.\n }\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAuB3B,YAAY,EACV,aACA,gBACA,mBACA,kBACA,cAOC;0BAjCqC,EAAE;4BAC6B;sBAIjC;qBAKD;2BAGA;oBAKR;qBACP,QAAQA,IAAQ;AAepC,OAAK,cAAc;AACnB,OAAK,iBAAiB;AACtB,OAAK,oBAAoB,qBAAqB,qBAAqB;AAEnE,MAAI,KAAK,kBACP;AAGF,OAAK,cAAc,WAAW;AAO9B,OAAK,UAAU,IAAI,UAAU,EAC3B,UAJA,QAAQ,IAAI,gCACZ,oCAID,CAAC;AAEF,OAAK,oBAAoB;GACvB,2BAA2B;GAC3B,8BAA8B;GAC/B,CAAC;;CAGJ,AAAQ,kBAAkB;AAExB,SADqB,KAAK,QAAQ,GACZ,KAAK;;CAG7B,MAAM,QACJ,OACA,YACA;AACA,MAAI,KAAK,kBACP;AAOF,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,iBAAiB,CAC9C;EAQF,MAAM,sBAAsB,KAAK,cAAc,IAAI,KAAK;EACxD,MAAM,eAAe;GACnB,YAAY;GACZ,4BAA4B,IAAI;GAChC,cAAc,IAAI;GACnB;EAED,MAAM,sBAAsB,cAAc,WAAW;EACrD,MAAM,uBAAuB;GAC3B,GAAG,KAAK;GACR,GAAG;GACH,GAAG;GACJ;EACD,MAAM,8BAA8B,OAAO,KAAK,qBAAqB,CAClE,MAAM,CACN,QACE,KAAK,QAAQ;AACZ,OAAI,OAAO,qBAAqB;AAChC,UAAO;KAET,EAAE,CACH;AAEH,QAAMC,sBAAa,KAAK;GACtB;GACA,YAAY;GACZ,kBAAkB;IAAE,GAAG,KAAK;IAAkB,GAAG;IAAc;GAC/D,aAAa,KAAK;GAClB,gBAAgB,KAAK;GACrB,cAAc,KAAK,gBAAgB;GACpC,CAAC;AAEF,MAAI,KAAK,QACP,MAAK,QAAQ,MAAM;GACjB,aAAa,KAAK;GAClB;GACA,YAAY,EAAE,GAAG,6BAA6B;GAC/C,CAAC;;CAIN,oBAAoB,YAAiC;EACnD,MAAM,sBAAsB,cAAc,WAAW;AACrD,OAAK,mBAAmB;GACtB,GAAG,KAAK;GACR,GAAG;GACJ;;CAGH,sBAAsB,YAAuD;AAC3E,OAAK,qBAAqB;AAE1B,OAAK,oBAAoB,EACvB,OAAO;GACL,cAAc,WAAW;GACzB,SAAS,WAAW;GACrB,EACF,CAAC;;CAMJ,gBAAgB,cAAsB;AACpC,OAAK,eAAe;AACpB,OAAK,cAAc,wBAAwB,aAAa;;CAG1D,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAG5B,MAAI,QAAQ,IAAI,iCAEd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAOxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa"}
@@ -44,7 +44,7 @@ Alternatively, useCopilotChat is available for basic programmatic control, and d
44
44
 
45
45
  To learn more about premium features, read the documentation here:
46
46
 
47
- %chttps://docs.copilotkit.ai/premium%c`, ConsoleStyles.header, ConsoleStyles.body, ConsoleStyles.cta, ConsoleStyles.body, ConsoleStyles.link, ConsoleStyles.body);
47
+ %chttps://docs.copilotkit.ai/premium/overview%c`, ConsoleStyles.header, ConsoleStyles.body, ConsoleStyles.cta, ConsoleStyles.body, ConsoleStyles.link, ConsoleStyles.body);
48
48
  }
49
49
  function publicApiKeyRequired(feature) {
50
50
  console.log(`
@@ -1 +1 @@
1
- {"version":3,"file":"console-styling.cjs","names":[],"sources":["../../src/utils/console-styling.ts"],"sourcesContent":["/**\n * Console styling utilities for CopilotKit branded messages\n * Provides consistent, readable colors across light and dark console themes\n */\n\n/**\n * Color palette optimized for console readability\n */\nexport const ConsoleColors = {\n /** Primary brand blue - for titles and links */\n primary: \"#007acc\",\n /** Success green - for positive messaging */\n success: \"#22c55e\",\n /** Purple - for feature highlights */\n feature: \"#a855f7\",\n /** Red - for calls-to-action */\n cta: \"#ef4444\",\n /** Cyan - for closing statements */\n info: \"#06b6d4\",\n /** Inherit console default - for body text */\n inherit: \"inherit\",\n /** Warning style */\n warning: \"#f59e0b\",\n} as const;\n\n/**\n * Console style templates for common patterns\n */\nexport const ConsoleStyles = {\n /** Large header style */\n header: `color: ${ConsoleColors.warning}; font-weight: bold; font-size: 16px;`,\n /** Section header style */\n section: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Feature highlight style */\n highlight: `color: ${ConsoleColors.feature}; font-weight: bold;`,\n /** Call-to-action style */\n cta: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Info style */\n info: `color: ${ConsoleColors.info}; font-weight: bold;`,\n /** Link style */\n link: `color: ${ConsoleColors.primary}; text-decoration: underline;`,\n /** Body text - inherits console theme */\n body: `color: ${ConsoleColors.inherit};`,\n /** Warning style */\n warning: `color: ${ConsoleColors.cta}; font-weight: bold;`,\n} as const;\n\n/**\n * Styled console message for CopilotKit Platform promotion\n * Displays a beautiful, branded advertisement in the console\n */\nexport function logCopilotKitPlatformMessage() {\n console.log(\n `%cCopilotKit Warning%c\n\nuseCopilotChatHeadless_c provides full compatibility with CopilotKit's newly released Headless UI feature set. To enable this premium feature, add your public license key, available for free at:\n\n%chttps://cloud.copilotkit.ai%c\n\nAlternatively, useCopilotChat is available for basic programmatic control, and does not require an API key.\n\nTo learn more about premium features, read the documentation here:\n\n%chttps://docs.copilotkit.ai/premium%c`,\n ConsoleStyles.header,\n ConsoleStyles.body,\n ConsoleStyles.cta,\n ConsoleStyles.body,\n ConsoleStyles.link,\n ConsoleStyles.body,\n );\n}\n\nexport function publicApiKeyRequired(feature: string) {\n console.log(\n `\n%cCopilotKit Warning%c \\n\nIn order to use ${feature}, you need to add your CopilotKit API key, available for free at https://cloud.copilotkit.ai.\n `.trim(),\n ConsoleStyles.header,\n ConsoleStyles.body,\n );\n}\n\n/**\n * Create a styled console message with custom content\n *\n * @param template - Template string with %c placeholders\n * @param styles - Array of style strings matching the %c placeholders\n *\n * @example\n * ```typescript\n * logStyled(\n * '%cCopilotKit%c Welcome to the platform!',\n * [ConsoleStyles.header, ConsoleStyles.body]\n * );\n * ```\n */\nexport function logStyled(template: string, styles: string[]) {\n console.log(template, ...styles);\n}\n\n/**\n * Quick styled console methods for common use cases\n */\nexport const styledConsole = {\n /** Log a success message */\n success: (message: string) =>\n logStyled(`%c✅ ${message}`, [ConsoleStyles.section]),\n\n /** Log an info message */\n info: (message: string) => logStyled(`%cℹ️ ${message}`, [ConsoleStyles.info]),\n\n /** Log a feature highlight */\n feature: (message: string) =>\n logStyled(`%c✨ ${message}`, [ConsoleStyles.highlight]),\n\n /** Log a call-to-action */\n cta: (message: string) => logStyled(`%c🚀 ${message}`, [ConsoleStyles.cta]),\n\n /** Log the CopilotKit platform promotion */\n logCopilotKitPlatformMessage: logCopilotKitPlatformMessage,\n\n /** Log a `publicApiKeyRequired` warning */\n publicApiKeyRequired: publicApiKeyRequired,\n} as const;\n"],"mappings":";;;;;;;;;AAQA,MAAa,gBAAgB;CAE3B,SAAS;CAET,SAAS;CAET,SAAS;CAET,KAAK;CAEL,MAAM;CAEN,SAAS;CAET,SAAS;CACV;;;;AAKD,MAAa,gBAAgB;CAE3B,QAAQ,UAAU,cAAc,QAAQ;CAExC,SAAS,UAAU,cAAc,QAAQ;CAEzC,WAAW,UAAU,cAAc,QAAQ;CAE3C,KAAK,UAAU,cAAc,QAAQ;CAErC,MAAM,UAAU,cAAc,KAAK;CAEnC,MAAM,UAAU,cAAc,QAAQ;CAEtC,MAAM,UAAU,cAAc,QAAQ;CAEtC,SAAS,UAAU,cAAc,IAAI;CACtC;;;;;AAMD,SAAgB,+BAA+B;AAC7C,SAAQ,IACN;;;;;;;;;;yCAWA,cAAc,QACd,cAAc,MACd,cAAc,KACd,cAAc,MACd,cAAc,MACd,cAAc,KACf;;AAGH,SAAgB,qBAAqB,SAAiB;AACpD,SAAQ,IACN;;kBAEc,QAAQ;MACpB,MAAM,EACR,cAAc,QACd,cAAc,KACf;;;;;;;;;;;;;;;;AAiBH,SAAgB,UAAU,UAAkB,QAAkB;AAC5D,SAAQ,IAAI,UAAU,GAAG,OAAO;;;;;AAMlC,MAAa,gBAAgB;CAE3B,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,QAAQ,CAAC;CAGtD,OAAO,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,KAAK,CAAC;CAG7E,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,UAAU,CAAC;CAGxD,MAAM,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,IAAI,CAAC;CAG7C;CAGR;CACvB"}
1
+ {"version":3,"file":"console-styling.cjs","names":[],"sources":["../../src/utils/console-styling.ts"],"sourcesContent":["/**\n * Console styling utilities for CopilotKit branded messages\n * Provides consistent, readable colors across light and dark console themes\n */\n\n/**\n * Color palette optimized for console readability\n */\nexport const ConsoleColors = {\n /** Primary brand blue - for titles and links */\n primary: \"#007acc\",\n /** Success green - for positive messaging */\n success: \"#22c55e\",\n /** Purple - for feature highlights */\n feature: \"#a855f7\",\n /** Red - for calls-to-action */\n cta: \"#ef4444\",\n /** Cyan - for closing statements */\n info: \"#06b6d4\",\n /** Inherit console default - for body text */\n inherit: \"inherit\",\n /** Warning style */\n warning: \"#f59e0b\",\n} as const;\n\n/**\n * Console style templates for common patterns\n */\nexport const ConsoleStyles = {\n /** Large header style */\n header: `color: ${ConsoleColors.warning}; font-weight: bold; font-size: 16px;`,\n /** Section header style */\n section: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Feature highlight style */\n highlight: `color: ${ConsoleColors.feature}; font-weight: bold;`,\n /** Call-to-action style */\n cta: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Info style */\n info: `color: ${ConsoleColors.info}; font-weight: bold;`,\n /** Link style */\n link: `color: ${ConsoleColors.primary}; text-decoration: underline;`,\n /** Body text - inherits console theme */\n body: `color: ${ConsoleColors.inherit};`,\n /** Warning style */\n warning: `color: ${ConsoleColors.cta}; font-weight: bold;`,\n} as const;\n\n/**\n * Styled console message for CopilotKit Platform promotion\n * Displays a beautiful, branded advertisement in the console\n */\nexport function logCopilotKitPlatformMessage() {\n console.log(\n `%cCopilotKit Warning%c\n\nuseCopilotChatHeadless_c provides full compatibility with CopilotKit's newly released Headless UI feature set. To enable this premium feature, add your public license key, available for free at:\n\n%chttps://cloud.copilotkit.ai%c\n\nAlternatively, useCopilotChat is available for basic programmatic control, and does not require an API key.\n\nTo learn more about premium features, read the documentation here:\n\n%chttps://docs.copilotkit.ai/premium/overview%c`,\n ConsoleStyles.header,\n ConsoleStyles.body,\n ConsoleStyles.cta,\n ConsoleStyles.body,\n ConsoleStyles.link,\n ConsoleStyles.body,\n );\n}\n\nexport function publicApiKeyRequired(feature: string) {\n console.log(\n `\n%cCopilotKit Warning%c \\n\nIn order to use ${feature}, you need to add your CopilotKit API key, available for free at https://cloud.copilotkit.ai.\n `.trim(),\n ConsoleStyles.header,\n ConsoleStyles.body,\n );\n}\n\n/**\n * Create a styled console message with custom content\n *\n * @param template - Template string with %c placeholders\n * @param styles - Array of style strings matching the %c placeholders\n *\n * @example\n * ```typescript\n * logStyled(\n * '%cCopilotKit%c Welcome to the platform!',\n * [ConsoleStyles.header, ConsoleStyles.body]\n * );\n * ```\n */\nexport function logStyled(template: string, styles: string[]) {\n console.log(template, ...styles);\n}\n\n/**\n * Quick styled console methods for common use cases\n */\nexport const styledConsole = {\n /** Log a success message */\n success: (message: string) =>\n logStyled(`%c✅ ${message}`, [ConsoleStyles.section]),\n\n /** Log an info message */\n info: (message: string) => logStyled(`%cℹ️ ${message}`, [ConsoleStyles.info]),\n\n /** Log a feature highlight */\n feature: (message: string) =>\n logStyled(`%c✨ ${message}`, [ConsoleStyles.highlight]),\n\n /** Log a call-to-action */\n cta: (message: string) => logStyled(`%c🚀 ${message}`, [ConsoleStyles.cta]),\n\n /** Log the CopilotKit platform promotion */\n logCopilotKitPlatformMessage: logCopilotKitPlatformMessage,\n\n /** Log a `publicApiKeyRequired` warning */\n publicApiKeyRequired: publicApiKeyRequired,\n} as const;\n"],"mappings":";;;;;;;;;AAQA,MAAa,gBAAgB;CAE3B,SAAS;CAET,SAAS;CAET,SAAS;CAET,KAAK;CAEL,MAAM;CAEN,SAAS;CAET,SAAS;CACV;;;;AAKD,MAAa,gBAAgB;CAE3B,QAAQ,UAAU,cAAc,QAAQ;CAExC,SAAS,UAAU,cAAc,QAAQ;CAEzC,WAAW,UAAU,cAAc,QAAQ;CAE3C,KAAK,UAAU,cAAc,QAAQ;CAErC,MAAM,UAAU,cAAc,KAAK;CAEnC,MAAM,UAAU,cAAc,QAAQ;CAEtC,MAAM,UAAU,cAAc,QAAQ;CAEtC,SAAS,UAAU,cAAc,IAAI;CACtC;;;;;AAMD,SAAgB,+BAA+B;AAC7C,SAAQ,IACN;;;;;;;;;;kDAWA,cAAc,QACd,cAAc,MACd,cAAc,KACd,cAAc,MACd,cAAc,MACd,cAAc,KACf;;AAGH,SAAgB,qBAAqB,SAAiB;AACpD,SAAQ,IACN;;kBAEc,QAAQ;MACpB,MAAM,EACR,cAAc,QACd,cAAc,KACf;;;;;;;;;;;;;;;;AAiBH,SAAgB,UAAU,UAAkB,QAAkB;AAC5D,SAAQ,IAAI,UAAU,GAAG,OAAO;;;;;AAMlC,MAAa,gBAAgB;CAE3B,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,QAAQ,CAAC;CAGtD,OAAO,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,KAAK,CAAC;CAG7E,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,UAAU,CAAC;CAGxD,MAAM,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,IAAI,CAAC;CAG7C;CAGR;CACvB"}
@@ -43,7 +43,7 @@ Alternatively, useCopilotChat is available for basic programmatic control, and d
43
43
 
44
44
  To learn more about premium features, read the documentation here:
45
45
 
46
- %chttps://docs.copilotkit.ai/premium%c`, ConsoleStyles.header, ConsoleStyles.body, ConsoleStyles.cta, ConsoleStyles.body, ConsoleStyles.link, ConsoleStyles.body);
46
+ %chttps://docs.copilotkit.ai/premium/overview%c`, ConsoleStyles.header, ConsoleStyles.body, ConsoleStyles.cta, ConsoleStyles.body, ConsoleStyles.link, ConsoleStyles.body);
47
47
  }
48
48
  function publicApiKeyRequired(feature) {
49
49
  console.log(`
@@ -1 +1 @@
1
- {"version":3,"file":"console-styling.mjs","names":[],"sources":["../../src/utils/console-styling.ts"],"sourcesContent":["/**\n * Console styling utilities for CopilotKit branded messages\n * Provides consistent, readable colors across light and dark console themes\n */\n\n/**\n * Color palette optimized for console readability\n */\nexport const ConsoleColors = {\n /** Primary brand blue - for titles and links */\n primary: \"#007acc\",\n /** Success green - for positive messaging */\n success: \"#22c55e\",\n /** Purple - for feature highlights */\n feature: \"#a855f7\",\n /** Red - for calls-to-action */\n cta: \"#ef4444\",\n /** Cyan - for closing statements */\n info: \"#06b6d4\",\n /** Inherit console default - for body text */\n inherit: \"inherit\",\n /** Warning style */\n warning: \"#f59e0b\",\n} as const;\n\n/**\n * Console style templates for common patterns\n */\nexport const ConsoleStyles = {\n /** Large header style */\n header: `color: ${ConsoleColors.warning}; font-weight: bold; font-size: 16px;`,\n /** Section header style */\n section: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Feature highlight style */\n highlight: `color: ${ConsoleColors.feature}; font-weight: bold;`,\n /** Call-to-action style */\n cta: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Info style */\n info: `color: ${ConsoleColors.info}; font-weight: bold;`,\n /** Link style */\n link: `color: ${ConsoleColors.primary}; text-decoration: underline;`,\n /** Body text - inherits console theme */\n body: `color: ${ConsoleColors.inherit};`,\n /** Warning style */\n warning: `color: ${ConsoleColors.cta}; font-weight: bold;`,\n} as const;\n\n/**\n * Styled console message for CopilotKit Platform promotion\n * Displays a beautiful, branded advertisement in the console\n */\nexport function logCopilotKitPlatformMessage() {\n console.log(\n `%cCopilotKit Warning%c\n\nuseCopilotChatHeadless_c provides full compatibility with CopilotKit's newly released Headless UI feature set. To enable this premium feature, add your public license key, available for free at:\n\n%chttps://cloud.copilotkit.ai%c\n\nAlternatively, useCopilotChat is available for basic programmatic control, and does not require an API key.\n\nTo learn more about premium features, read the documentation here:\n\n%chttps://docs.copilotkit.ai/premium%c`,\n ConsoleStyles.header,\n ConsoleStyles.body,\n ConsoleStyles.cta,\n ConsoleStyles.body,\n ConsoleStyles.link,\n ConsoleStyles.body,\n );\n}\n\nexport function publicApiKeyRequired(feature: string) {\n console.log(\n `\n%cCopilotKit Warning%c \\n\nIn order to use ${feature}, you need to add your CopilotKit API key, available for free at https://cloud.copilotkit.ai.\n `.trim(),\n ConsoleStyles.header,\n ConsoleStyles.body,\n );\n}\n\n/**\n * Create a styled console message with custom content\n *\n * @param template - Template string with %c placeholders\n * @param styles - Array of style strings matching the %c placeholders\n *\n * @example\n * ```typescript\n * logStyled(\n * '%cCopilotKit%c Welcome to the platform!',\n * [ConsoleStyles.header, ConsoleStyles.body]\n * );\n * ```\n */\nexport function logStyled(template: string, styles: string[]) {\n console.log(template, ...styles);\n}\n\n/**\n * Quick styled console methods for common use cases\n */\nexport const styledConsole = {\n /** Log a success message */\n success: (message: string) =>\n logStyled(`%c✅ ${message}`, [ConsoleStyles.section]),\n\n /** Log an info message */\n info: (message: string) => logStyled(`%cℹ️ ${message}`, [ConsoleStyles.info]),\n\n /** Log a feature highlight */\n feature: (message: string) =>\n logStyled(`%c✨ ${message}`, [ConsoleStyles.highlight]),\n\n /** Log a call-to-action */\n cta: (message: string) => logStyled(`%c🚀 ${message}`, [ConsoleStyles.cta]),\n\n /** Log the CopilotKit platform promotion */\n logCopilotKitPlatformMessage: logCopilotKitPlatformMessage,\n\n /** Log a `publicApiKeyRequired` warning */\n publicApiKeyRequired: publicApiKeyRequired,\n} as const;\n"],"mappings":";;;;;;;;AAQA,MAAa,gBAAgB;CAE3B,SAAS;CAET,SAAS;CAET,SAAS;CAET,KAAK;CAEL,MAAM;CAEN,SAAS;CAET,SAAS;CACV;;;;AAKD,MAAa,gBAAgB;CAE3B,QAAQ,UAAU,cAAc,QAAQ;CAExC,SAAS,UAAU,cAAc,QAAQ;CAEzC,WAAW,UAAU,cAAc,QAAQ;CAE3C,KAAK,UAAU,cAAc,QAAQ;CAErC,MAAM,UAAU,cAAc,KAAK;CAEnC,MAAM,UAAU,cAAc,QAAQ;CAEtC,MAAM,UAAU,cAAc,QAAQ;CAEtC,SAAS,UAAU,cAAc,IAAI;CACtC;;;;;AAMD,SAAgB,+BAA+B;AAC7C,SAAQ,IACN;;;;;;;;;;yCAWA,cAAc,QACd,cAAc,MACd,cAAc,KACd,cAAc,MACd,cAAc,MACd,cAAc,KACf;;AAGH,SAAgB,qBAAqB,SAAiB;AACpD,SAAQ,IACN;;kBAEc,QAAQ;MACpB,MAAM,EACR,cAAc,QACd,cAAc,KACf;;;;;;;;;;;;;;;;AAiBH,SAAgB,UAAU,UAAkB,QAAkB;AAC5D,SAAQ,IAAI,UAAU,GAAG,OAAO;;;;;AAMlC,MAAa,gBAAgB;CAE3B,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,QAAQ,CAAC;CAGtD,OAAO,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,KAAK,CAAC;CAG7E,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,UAAU,CAAC;CAGxD,MAAM,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,IAAI,CAAC;CAG7C;CAGR;CACvB"}
1
+ {"version":3,"file":"console-styling.mjs","names":[],"sources":["../../src/utils/console-styling.ts"],"sourcesContent":["/**\n * Console styling utilities for CopilotKit branded messages\n * Provides consistent, readable colors across light and dark console themes\n */\n\n/**\n * Color palette optimized for console readability\n */\nexport const ConsoleColors = {\n /** Primary brand blue - for titles and links */\n primary: \"#007acc\",\n /** Success green - for positive messaging */\n success: \"#22c55e\",\n /** Purple - for feature highlights */\n feature: \"#a855f7\",\n /** Red - for calls-to-action */\n cta: \"#ef4444\",\n /** Cyan - for closing statements */\n info: \"#06b6d4\",\n /** Inherit console default - for body text */\n inherit: \"inherit\",\n /** Warning style */\n warning: \"#f59e0b\",\n} as const;\n\n/**\n * Console style templates for common patterns\n */\nexport const ConsoleStyles = {\n /** Large header style */\n header: `color: ${ConsoleColors.warning}; font-weight: bold; font-size: 16px;`,\n /** Section header style */\n section: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Feature highlight style */\n highlight: `color: ${ConsoleColors.feature}; font-weight: bold;`,\n /** Call-to-action style */\n cta: `color: ${ConsoleColors.success}; font-weight: bold;`,\n /** Info style */\n info: `color: ${ConsoleColors.info}; font-weight: bold;`,\n /** Link style */\n link: `color: ${ConsoleColors.primary}; text-decoration: underline;`,\n /** Body text - inherits console theme */\n body: `color: ${ConsoleColors.inherit};`,\n /** Warning style */\n warning: `color: ${ConsoleColors.cta}; font-weight: bold;`,\n} as const;\n\n/**\n * Styled console message for CopilotKit Platform promotion\n * Displays a beautiful, branded advertisement in the console\n */\nexport function logCopilotKitPlatformMessage() {\n console.log(\n `%cCopilotKit Warning%c\n\nuseCopilotChatHeadless_c provides full compatibility with CopilotKit's newly released Headless UI feature set. To enable this premium feature, add your public license key, available for free at:\n\n%chttps://cloud.copilotkit.ai%c\n\nAlternatively, useCopilotChat is available for basic programmatic control, and does not require an API key.\n\nTo learn more about premium features, read the documentation here:\n\n%chttps://docs.copilotkit.ai/premium/overview%c`,\n ConsoleStyles.header,\n ConsoleStyles.body,\n ConsoleStyles.cta,\n ConsoleStyles.body,\n ConsoleStyles.link,\n ConsoleStyles.body,\n );\n}\n\nexport function publicApiKeyRequired(feature: string) {\n console.log(\n `\n%cCopilotKit Warning%c \\n\nIn order to use ${feature}, you need to add your CopilotKit API key, available for free at https://cloud.copilotkit.ai.\n `.trim(),\n ConsoleStyles.header,\n ConsoleStyles.body,\n );\n}\n\n/**\n * Create a styled console message with custom content\n *\n * @param template - Template string with %c placeholders\n * @param styles - Array of style strings matching the %c placeholders\n *\n * @example\n * ```typescript\n * logStyled(\n * '%cCopilotKit%c Welcome to the platform!',\n * [ConsoleStyles.header, ConsoleStyles.body]\n * );\n * ```\n */\nexport function logStyled(template: string, styles: string[]) {\n console.log(template, ...styles);\n}\n\n/**\n * Quick styled console methods for common use cases\n */\nexport const styledConsole = {\n /** Log a success message */\n success: (message: string) =>\n logStyled(`%c✅ ${message}`, [ConsoleStyles.section]),\n\n /** Log an info message */\n info: (message: string) => logStyled(`%cℹ️ ${message}`, [ConsoleStyles.info]),\n\n /** Log a feature highlight */\n feature: (message: string) =>\n logStyled(`%c✨ ${message}`, [ConsoleStyles.highlight]),\n\n /** Log a call-to-action */\n cta: (message: string) => logStyled(`%c🚀 ${message}`, [ConsoleStyles.cta]),\n\n /** Log the CopilotKit platform promotion */\n logCopilotKitPlatformMessage: logCopilotKitPlatformMessage,\n\n /** Log a `publicApiKeyRequired` warning */\n publicApiKeyRequired: publicApiKeyRequired,\n} as const;\n"],"mappings":";;;;;;;;AAQA,MAAa,gBAAgB;CAE3B,SAAS;CAET,SAAS;CAET,SAAS;CAET,KAAK;CAEL,MAAM;CAEN,SAAS;CAET,SAAS;CACV;;;;AAKD,MAAa,gBAAgB;CAE3B,QAAQ,UAAU,cAAc,QAAQ;CAExC,SAAS,UAAU,cAAc,QAAQ;CAEzC,WAAW,UAAU,cAAc,QAAQ;CAE3C,KAAK,UAAU,cAAc,QAAQ;CAErC,MAAM,UAAU,cAAc,KAAK;CAEnC,MAAM,UAAU,cAAc,QAAQ;CAEtC,MAAM,UAAU,cAAc,QAAQ;CAEtC,SAAS,UAAU,cAAc,IAAI;CACtC;;;;;AAMD,SAAgB,+BAA+B;AAC7C,SAAQ,IACN;;;;;;;;;;kDAWA,cAAc,QACd,cAAc,MACd,cAAc,KACd,cAAc,MACd,cAAc,MACd,cAAc,KACf;;AAGH,SAAgB,qBAAqB,SAAiB;AACpD,SAAQ,IACN;;kBAEc,QAAQ;MACpB,MAAM,EACR,cAAc,QACd,cAAc,KACf;;;;;;;;;;;;;;;;AAiBH,SAAgB,UAAU,UAAkB,QAAkB;AAC5D,SAAQ,IAAI,UAAU,GAAG,OAAO;;;;;AAMlC,MAAa,gBAAgB;CAE3B,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,QAAQ,CAAC;CAGtD,OAAO,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,KAAK,CAAC;CAG7E,UAAU,YACR,UAAU,OAAO,WAAW,CAAC,cAAc,UAAU,CAAC;CAGxD,MAAM,YAAoB,UAAU,QAAQ,WAAW,CAAC,cAAc,IAAI,CAAC;CAG7C;CAGR;CACvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/shared",
3
- "version": "1.57.3",
3
+ "version": "1.58.0-canary.thread-id-propagation",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "ai",
@@ -1 +1,7 @@
1
1
  export * from "./telemetry-client";
2
+ export { default as lambdaClient } from "./lambda-client";
3
+ export {
4
+ parseTelemetryIdFromLicense,
5
+ parseAndWarnTelemetryId,
6
+ } from "./lambda-client";
7
+ export type { LambdaSendOptions } from "./lambda-client";