@copilotkit/runtime 1.68.3-canary.1787220377 → 1.68.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"single-route-helpers.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/single-route-helpers.ts"],"sourcesContent":["const METHOD_NAMES = [\n \"agent/run\",\n \"agent/suggest\",\n \"agent/connect\",\n \"agent/stop\",\n \"info\",\n \"inspector/metadata\",\n \"transcribe\",\n] as const;\n\nexport type EndpointMethod = (typeof METHOD_NAMES)[number];\n\ninterface JsonEnvelope {\n method?: string;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport interface MethodCall {\n method: EndpointMethod;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport async function parseMethodCall(request: Request): Promise<MethodCall> {\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"application/json\")) {\n throw createResponseError(\n \"Single-route endpoint expects JSON payloads\",\n 415,\n );\n }\n\n let jsonEnvelope: JsonEnvelope;\n try {\n jsonEnvelope = (await request.clone().json()) as JsonEnvelope;\n } catch {\n throw createResponseError(\"Invalid JSON payload\", 400);\n }\n\n const method = validateMethod(jsonEnvelope.method);\n\n return {\n method,\n params: jsonEnvelope.params,\n body: jsonEnvelope.body,\n };\n}\n\nexport function expectString(\n params: Record<string, unknown> | undefined,\n key: string,\n): string {\n const value = params?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n throw createResponseError(`Missing or invalid parameter '${key}'`, 400);\n}\n\nexport function createJsonRequest(base: Request, body: unknown): Request {\n if (body === undefined || body === null) {\n throw createResponseError(\"Missing request body for JSON handler\", 400);\n }\n\n const headers = new Headers(base.headers);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const serializedBody = serializeJsonBody(body);\n\n return new Request(base.url, {\n method: \"POST\",\n headers,\n body: serializedBody,\n signal: base.signal,\n });\n}\n\nexport function createResponseError(message: string, status: number): Response {\n return new Response(\n JSON.stringify({\n error: \"invalid_request\",\n message,\n }),\n {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n}\n\nfunction validateMethod(method: string | undefined): EndpointMethod {\n if (!method) {\n throw createResponseError(\"Missing method field\", 400);\n }\n\n if ((METHOD_NAMES as readonly string[]).includes(method)) {\n return method as EndpointMethod;\n }\n\n throw createResponseError(`Unsupported method '${method}'`, 400);\n}\n\nfunction serializeJsonBody(body: unknown): BodyInit {\n if (typeof body === \"string\") {\n return body;\n }\n\n if (\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n body instanceof Uint8Array\n ) {\n // Uint8Array<ArrayBufferLike> is a valid fetch body at runtime, but the\n // DOM lib's BodyInit only admits ArrayBuffer-backed views.\n return body as BodyInit;\n }\n\n if (body instanceof FormData || body instanceof URLSearchParams) {\n return body;\n }\n\n return JSON.stringify(body);\n}\n"],"mappings":";;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAgBD,eAAsB,gBAAgB,SAAuC;AAG3E,KAAI,EAFgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAE1C,SAAS,mBAAmB,CAC3C,OAAM,oBACJ,+CACA,IACD;CAGH,IAAI;AACJ,KAAI;AACF,iBAAgB,MAAM,QAAQ,OAAO,CAAC,MAAM;SACtC;AACN,QAAM,oBAAoB,wBAAwB,IAAI;;AAKxD,QAAO;EACL,QAHa,eAAe,aAAa,OAAO;EAIhD,QAAQ,aAAa;EACrB,MAAM,aAAa;EACpB;;AAGH,SAAgB,aACd,QACA,KACQ;CACR,MAAM,QAAQ,SAAS;AACvB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;AAGT,OAAM,oBAAoB,iCAAiC,IAAI,IAAI,IAAI;;AAGzE,SAAgB,kBAAkB,MAAe,MAAwB;AACvE,KAAI,SAAS,UAAa,SAAS,KACjC,OAAM,oBAAoB,yCAAyC,IAAI;CAGzE,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,IAAI,gBAAgB,mBAAmB;AAC/C,SAAQ,OAAO,iBAAiB;CAEhC,MAAM,iBAAiB,kBAAkB,KAAK;AAE9C,QAAO,IAAI,QAAQ,KAAK,KAAK;EAC3B,QAAQ;EACR;EACA,MAAM;EACN,QAAQ,KAAK;EACd,CAAC;;AAGJ,SAAgB,oBAAoB,SAAiB,QAA0B;AAC7E,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP;EACD,CAAC,EACF;EACE;EACA,SAAS,EACP,gBAAgB,oBACjB;EACF,CACF;;AAGH,SAAS,eAAe,QAA4C;AAClE,KAAI,CAAC,OACH,OAAM,oBAAoB,wBAAwB,IAAI;AAGxD,KAAK,aAAmC,SAAS,OAAO,CACtD,QAAO;AAGT,OAAM,oBAAoB,uBAAuB,OAAO,IAAI,IAAI;;AAGlE,SAAS,kBAAkB,MAAyB;AAClD,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KACE,gBAAgB,QAChB,gBAAgB,eAChB,gBAAgB,WAIhB,QAAO;AAGT,KAAI,gBAAgB,YAAY,gBAAgB,gBAC9C,QAAO;AAGT,QAAO,KAAK,UAAU,KAAK"}
1
+ {"version":3,"file":"single-route-helpers.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/single-route-helpers.ts"],"sourcesContent":["const METHOD_NAMES = [\n \"agent/run\",\n \"agent/suggest\",\n \"agent/connect\",\n \"agent/stop\",\n \"info\",\n \"inspector/metadata\",\n \"transcribe\",\n] as const;\n\nexport type EndpointMethod = (typeof METHOD_NAMES)[number];\n\ninterface JsonEnvelope {\n method?: string;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\nexport interface MethodCall {\n method: EndpointMethod;\n params?: Record<string, unknown>;\n body?: unknown;\n}\n\n/**\n * Detect a single-route JSON envelope on a request the multi-route router\n * could not match.\n *\n * A single-endpoint client (`useSingleEndpoint` on the frontend provider)\n * POSTs `{ method, params, body }` at the base path. A multi-route runtime\n * matches no route for that path and would otherwise answer a bare 404, giving\n * the developer nothing to go on. Recognising the envelope here lets the\n * handler name the actual cause instead.\n *\n * Deliberately conservative: it reports a method only for a POST carrying a\n * JSON body whose `method` is one the single-route endpoint actually accepts.\n * Anything else is a genuine 404 and must stay one.\n *\n * @returns The envelope's method name, or `null` if this is not an envelope.\n */\nexport async function detectSingleRouteEnvelope(\n request: Request,\n): Promise<EndpointMethod | null> {\n if (request.method !== \"POST\") return null;\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) return null;\n\n let envelope: unknown;\n try {\n envelope = await request.clone().json();\n } catch {\n return null;\n }\n\n if (typeof envelope !== \"object\" || envelope === null) return null;\n\n const method = (envelope as JsonEnvelope).method;\n if (typeof method !== \"string\") return null;\n if (!(METHOD_NAMES as readonly string[]).includes(method)) return null;\n\n return method as EndpointMethod;\n}\n\nexport async function parseMethodCall(request: Request): Promise<MethodCall> {\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"application/json\")) {\n throw createResponseError(\n \"Single-route endpoint expects JSON payloads\",\n 415,\n );\n }\n\n let jsonEnvelope: JsonEnvelope;\n try {\n jsonEnvelope = (await request.clone().json()) as JsonEnvelope;\n } catch {\n throw createResponseError(\"Invalid JSON payload\", 400);\n }\n\n const method = validateMethod(jsonEnvelope.method);\n\n return {\n method,\n params: jsonEnvelope.params,\n body: jsonEnvelope.body,\n };\n}\n\nexport function expectString(\n params: Record<string, unknown> | undefined,\n key: string,\n): string {\n const value = params?.[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n throw createResponseError(`Missing or invalid parameter '${key}'`, 400);\n}\n\nexport function createJsonRequest(base: Request, body: unknown): Request {\n if (body === undefined || body === null) {\n throw createResponseError(\"Missing request body for JSON handler\", 400);\n }\n\n const headers = new Headers(base.headers);\n headers.set(\"content-type\", \"application/json\");\n headers.delete(\"content-length\");\n\n const serializedBody = serializeJsonBody(body);\n\n return new Request(base.url, {\n method: \"POST\",\n headers,\n body: serializedBody,\n signal: base.signal,\n });\n}\n\nexport function createResponseError(message: string, status: number): Response {\n return new Response(\n JSON.stringify({\n error: \"invalid_request\",\n message,\n }),\n {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n );\n}\n\nfunction validateMethod(method: string | undefined): EndpointMethod {\n if (!method) {\n throw createResponseError(\"Missing method field\", 400);\n }\n\n if ((METHOD_NAMES as readonly string[]).includes(method)) {\n return method as EndpointMethod;\n }\n\n throw createResponseError(`Unsupported method '${method}'`, 400);\n}\n\nfunction serializeJsonBody(body: unknown): BodyInit {\n if (typeof body === \"string\") {\n return body;\n }\n\n if (\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n body instanceof Uint8Array\n ) {\n // Uint8Array<ArrayBufferLike> is a valid fetch body at runtime, but the\n // DOM lib's BodyInit only admits ArrayBuffer-backed views.\n return body as BodyInit;\n }\n\n if (body instanceof FormData || body instanceof URLSearchParams) {\n return body;\n }\n\n return JSON.stringify(body);\n}\n"],"mappings":";;AAAA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;;;;;;;;;;AAgCD,eAAsB,0BACpB,SACgC;AAChC,KAAI,QAAQ,WAAW,OAAQ,QAAO;AAGtC,KAAI,EADgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAC1C,SAAS,mBAAmB,CAAE,QAAO;CAEtD,IAAI;AACJ,KAAI;AACF,aAAW,MAAM,QAAQ,OAAO,CAAC,MAAM;SACjC;AACN,SAAO;;AAGT,KAAI,OAAO,aAAa,YAAY,aAAa,KAAM,QAAO;CAE9D,MAAM,SAAU,SAA0B;AAC1C,KAAI,OAAO,WAAW,SAAU,QAAO;AACvC,KAAI,CAAE,aAAmC,SAAS,OAAO,CAAE,QAAO;AAElE,QAAO;;AAGT,eAAsB,gBAAgB,SAAuC;AAG3E,KAAI,EAFgB,QAAQ,QAAQ,IAAI,eAAe,IAAI,IAE1C,SAAS,mBAAmB,CAC3C,OAAM,oBACJ,+CACA,IACD;CAGH,IAAI;AACJ,KAAI;AACF,iBAAgB,MAAM,QAAQ,OAAO,CAAC,MAAM;SACtC;AACN,QAAM,oBAAoB,wBAAwB,IAAI;;AAKxD,QAAO;EACL,QAHa,eAAe,aAAa,OAAO;EAIhD,QAAQ,aAAa;EACrB,MAAM,aAAa;EACpB;;AAGH,SAAgB,aACd,QACA,KACQ;CACR,MAAM,QAAQ,SAAS;AACvB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;AAGT,OAAM,oBAAoB,iCAAiC,IAAI,IAAI,IAAI;;AAGzE,SAAgB,kBAAkB,MAAe,MAAwB;AACvE,KAAI,SAAS,UAAa,SAAS,KACjC,OAAM,oBAAoB,yCAAyC,IAAI;CAGzE,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ;AACzC,SAAQ,IAAI,gBAAgB,mBAAmB;AAC/C,SAAQ,OAAO,iBAAiB;CAEhC,MAAM,iBAAiB,kBAAkB,KAAK;AAE9C,QAAO,IAAI,QAAQ,KAAK,KAAK;EAC3B,QAAQ;EACR;EACA,MAAM;EACN,QAAQ,KAAK;EACd,CAAC;;AAGJ,SAAgB,oBAAoB,SAAiB,QAA0B;AAC7E,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP;EACD,CAAC,EACF;EACE;EACA,SAAS,EACP,gBAAgB,oBACjB;EACF,CACF;;AAGH,SAAS,eAAe,QAA4C;AAClE,KAAI,CAAC,OACH,OAAM,oBAAoB,wBAAwB,IAAI;AAGxD,KAAK,aAAmC,SAAS,OAAO,CACtD,QAAO;AAGT,OAAM,oBAAoB,uBAAuB,OAAO,IAAI,IAAI;;AAGlE,SAAS,kBAAkB,MAAyB;AAClD,KAAI,OAAO,SAAS,SAClB,QAAO;AAGT,KACE,gBAAgB,QAChB,gBAAgB,eAChB,gBAAgB,WAIhB,QAAO;AAGT,KAAI,gBAAgB,YAAY,gBAAgB,gBAC9C,QAAO;AAGT,QAAO,KAAK,UAAU,KAAK"}
@@ -14,6 +14,7 @@ var TelemetryClient = class {
14
14
  this.sampleRate = .05;
15
15
  this.licenseToken = null;
16
16
  this.telemetryId = null;
17
+ this.globalProperties = {};
17
18
  this.telemetryDisabled = telemetryDisabled ?? isTelemetryDisabled();
18
19
  this.setSampleRate(sampleRate);
19
20
  }
@@ -21,6 +22,19 @@ var TelemetryClient = class {
21
22
  if (this.sampleRate >= 1) return true;
22
23
  return Math.random() < this.sampleRate;
23
24
  }
25
+ /**
26
+ * Add properties carried by every subsequent event.
27
+ *
28
+ * Merged rather than replaced, so two callers setting different fields do not
29
+ * erase each other. Set once at runtime construction in practice; nothing
30
+ * here is per-request.
31
+ */
32
+ setGlobalProperties(properties) {
33
+ this.globalProperties = {
34
+ ...this.globalProperties,
35
+ ...properties
36
+ };
37
+ }
24
38
  setLicenseToken(licenseToken) {
25
39
  this.licenseToken = licenseToken;
26
40
  this.telemetryId = (0, _copilotkit_shared.parseAndWarnTelemetryId)(licenseToken);
@@ -31,6 +45,7 @@ var TelemetryClient = class {
31
45
  await _copilotkit_shared.lambdaClient.send({
32
46
  event,
33
47
  properties,
48
+ globalProperties: this.globalProperties,
34
49
  packageName: import_package.name,
35
50
  packageVersion: import_package.version,
36
51
  licenseToken: this.licenseToken ?? void 0
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.cjs","names":["lambdaClient","packageJson"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport { lambdaClient, parseAndWarnTelemetryId } from \"@copilotkit/shared\";\nimport * as packageJson from \"../../../../package.json\";\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 private telemetryDisabled: boolean = false;\n // Client-side sampling rate for anonymous events. Identified callers\n // (license token with telemetry_id) bypass the gate. Default 0.05\n // caps anonymous OSS-runtime egress; identified customers send at\n // full fidelity. Override via COPILOTKIT_TELEMETRY_SAMPLE_RATE.\n private sampleRate: number = 0.05;\n // EIP / Intelligence license token (Ed25519-signed JWT). The lambda\n // client decodes its payload to read telemetry_id for the\n // X-CopilotKit-Telemetry-Id header. Set once at runtime construction\n // via setLicenseToken; absent values produce anonymous sends.\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\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled ?? isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n setLicenseToken(licenseToken: string) {\n this.licenseToken = licenseToken;\n this.telemetryId = parseAndWarnTelemetryId(licenseToken);\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (this.telemetryDisabled) return;\n // Anonymous callers are gated by sampleRate; identified callers\n // (telemetry_id present) bypass the gate and always send.\n if (!this.telemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n packageName: packageJson.name,\n packageVersion: packageJson.version,\n licenseToken: this.licenseToken ?? undefined,\n });\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\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.\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 }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;;AAIA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAkB3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAvB6B;oBAKR;sBAKS;qBAKD;AASnC,OAAK,oBAAoB,qBAAqB,qBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;CAG9B,gBAAgB,cAAsB;AACpC,OAAK,eAAe;AACpB,OAAK,8DAAsC,aAAa;;CAG1D,MAAM,QACJ,OACA,YACA;AACA,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,iBAAiB,CAAE;AAElD,QAAMA,gCAAa,KAAK;GACtB;GACY;GACZ,aAAaC,eAAY;GACzB,gBAAgBA,eAAY;GAC5B,cAAc,KAAK,gBAAgB;GACpC,CAAC;;CAGJ,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAI,iBAAiB"}
1
+ {"version":3,"file":"telemetry-client.cjs","names":["lambdaClient","packageJson"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport { lambdaClient, parseAndWarnTelemetryId } from \"@copilotkit/shared\";\nimport * as packageJson from \"../../../../package.json\";\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 private telemetryDisabled: boolean = false;\n // Client-side sampling rate for anonymous events. Identified callers\n // (license token with telemetry_id) bypass the gate. Default 0.05\n // caps anonymous OSS-runtime egress; identified customers send at\n // full fidelity. Override via COPILOTKIT_TELEMETRY_SAMPLE_RATE.\n private sampleRate: number = 0.05;\n // EIP / Intelligence license token (Ed25519-signed JWT). The lambda\n // client decodes its payload to read telemetry_id for the\n // X-CopilotKit-Telemetry-Id header. Set once at runtime construction\n // via setLicenseToken; absent values produce anonymous sends.\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 // Properties merged into every event this client sends.\n //\n // For facts about the caller that are true for the whole process rather than\n // for one event: which product is embedding the runtime, for instance. A\n // distribution built on top of this can then be told apart in the existing\n // events instead of sending its own, which is the difference between one\n // extra field and a second pipeline nobody asked for.\n //\n // Sent as `global_properties`, a field of its own, so these stay separable\n // from an event's own properties all the way to the sink.\n //\n // Do not reuse a key an event already sets: the fanout spreads this bag last\n // for `oss.runtime.*`, so a collision resolves in favour of the global and\n // does so silently. Names here should describe the caller, not the call.\n private globalProperties: Record<string, unknown> = {};\n\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled ?? isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n /**\n * Add properties carried by every subsequent event.\n *\n * Merged rather than replaced, so two callers setting different fields do not\n * erase each other. Set once at runtime construction in practice; nothing\n * here is per-request.\n */\n setGlobalProperties(properties: Record<string, unknown>) {\n this.globalProperties = { ...this.globalProperties, ...properties };\n }\n\n setLicenseToken(licenseToken: string) {\n this.licenseToken = licenseToken;\n this.telemetryId = parseAndWarnTelemetryId(licenseToken);\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (this.telemetryDisabled) return;\n // Anonymous callers are gated by sampleRate; identified callers\n // (telemetry_id present) bypass the gate and always send.\n if (!this.telemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n // Its own field on the wire rather than folded into `properties`, which\n // is what the sink expects: for `oss.runtime.*` the fanout treats\n // `global_properties` as the SDK's pass-through bag and spreads it into\n // the analytics event, and v1's client sends package name and version the\n // same way. Folding it in would work and would put a process-level fact\n // in the per-event slot, where nothing downstream expects to find one.\n globalProperties: this.globalProperties,\n packageName: packageJson.name,\n packageVersion: packageJson.version,\n licenseToken: this.licenseToken ?? undefined,\n });\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\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.\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 }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;;AAIA,SAAgB,sBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAa,kBAAb,MAA6B;CAiC3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAtC6B;oBAKR;sBAKS;qBAKD;0BAee,EAAE;AASpD,OAAK,oBAAoB,qBAAqB,qBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;;;;;;;;CAU9B,oBAAoB,YAAqC;AACvD,OAAK,mBAAmB;GAAE,GAAG,KAAK;GAAkB,GAAG;GAAY;;CAGrE,gBAAgB,cAAsB;AACpC,OAAK,eAAe;AACpB,OAAK,8DAAsC,aAAa;;CAG1D,MAAM,QACJ,OACA,YACA;AACA,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,iBAAiB,CAAE;AAElD,QAAMA,gCAAa,KAAK;GACtB;GACY;GAOZ,kBAAkB,KAAK;GACvB,aAAaC,eAAY;GACzB,gBAAgBA,eAAY;GAC5B,cAAc,KAAK,gBAAgB;GACpC,CAAC;;CAGJ,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAI,iBAAiB"}
@@ -14,6 +14,7 @@ var TelemetryClient$1 = class {
14
14
  this.sampleRate = .05;
15
15
  this.licenseToken = null;
16
16
  this.telemetryId = null;
17
+ this.globalProperties = {};
17
18
  this.telemetryDisabled = telemetryDisabled ?? isTelemetryDisabled$1();
18
19
  this.setSampleRate(sampleRate);
19
20
  }
@@ -21,6 +22,19 @@ var TelemetryClient$1 = class {
21
22
  if (this.sampleRate >= 1) return true;
22
23
  return Math.random() < this.sampleRate;
23
24
  }
25
+ /**
26
+ * Add properties carried by every subsequent event.
27
+ *
28
+ * Merged rather than replaced, so two callers setting different fields do not
29
+ * erase each other. Set once at runtime construction in practice; nothing
30
+ * here is per-request.
31
+ */
32
+ setGlobalProperties(properties) {
33
+ this.globalProperties = {
34
+ ...this.globalProperties,
35
+ ...properties
36
+ };
37
+ }
24
38
  setLicenseToken(licenseToken) {
25
39
  this.licenseToken = licenseToken;
26
40
  this.telemetryId = parseAndWarnTelemetryId(licenseToken);
@@ -31,6 +45,7 @@ var TelemetryClient$1 = class {
31
45
  await lambdaClient.send({
32
46
  event,
33
47
  properties,
48
+ globalProperties: this.globalProperties,
34
49
  packageName: import_package.name,
35
50
  packageVersion: import_package.version,
36
51
  licenseToken: this.licenseToken ?? void 0
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-client.mjs","names":["isTelemetryDisabled","TelemetryClient","packageJson"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport { lambdaClient, parseAndWarnTelemetryId } from \"@copilotkit/shared\";\nimport * as packageJson from \"../../../../package.json\";\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 private telemetryDisabled: boolean = false;\n // Client-side sampling rate for anonymous events. Identified callers\n // (license token with telemetry_id) bypass the gate. Default 0.05\n // caps anonymous OSS-runtime egress; identified customers send at\n // full fidelity. Override via COPILOTKIT_TELEMETRY_SAMPLE_RATE.\n private sampleRate: number = 0.05;\n // EIP / Intelligence license token (Ed25519-signed JWT). The lambda\n // client decodes its payload to read telemetry_id for the\n // X-CopilotKit-Telemetry-Id header. Set once at runtime construction\n // via setLicenseToken; absent values produce anonymous sends.\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\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled ?? isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n setLicenseToken(licenseToken: string) {\n this.licenseToken = licenseToken;\n this.telemetryId = parseAndWarnTelemetryId(licenseToken);\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (this.telemetryDisabled) return;\n // Anonymous callers are gated by sampleRate; identified callers\n // (telemetry_id present) bypass the gate and always send.\n if (!this.telemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n packageName: packageJson.name,\n packageVersion: packageJson.version,\n licenseToken: this.licenseToken ?? undefined,\n });\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\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.\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 }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;;AAIA,SAAgBA,wBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAaC,oBAAb,MAA6B;CAkB3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAvB6B;oBAKR;sBAKS;qBAKD;AASnC,OAAK,oBAAoB,qBAAqBD,uBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;CAG9B,gBAAgB,cAAsB;AACpC,OAAK,eAAe;AACpB,OAAK,cAAc,wBAAwB,aAAa;;CAG1D,MAAM,QACJ,OACA,YACA;AACA,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,iBAAiB,CAAE;AAElD,QAAM,aAAa,KAAK;GACtB;GACY;GACZ,aAAaE,eAAY;GACzB,gBAAgBA,eAAY;GAC5B,cAAc,KAAK,gBAAgB;GACpC,CAAC;;CAGJ,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAID,mBAAiB"}
1
+ {"version":3,"file":"telemetry-client.mjs","names":["isTelemetryDisabled","TelemetryClient","packageJson"],"sources":["../../../../src/v2/runtime/telemetry/telemetry-client.ts"],"sourcesContent":["import type { AnalyticsEvents } from \"./events\";\nimport { lambdaClient, parseAndWarnTelemetryId } from \"@copilotkit/shared\";\nimport * as packageJson from \"../../../../package.json\";\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 private telemetryDisabled: boolean = false;\n // Client-side sampling rate for anonymous events. Identified callers\n // (license token with telemetry_id) bypass the gate. Default 0.05\n // caps anonymous OSS-runtime egress; identified customers send at\n // full fidelity. Override via COPILOTKIT_TELEMETRY_SAMPLE_RATE.\n private sampleRate: number = 0.05;\n // EIP / Intelligence license token (Ed25519-signed JWT). The lambda\n // client decodes its payload to read telemetry_id for the\n // X-CopilotKit-Telemetry-Id header. Set once at runtime construction\n // via setLicenseToken; absent values produce anonymous sends.\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 // Properties merged into every event this client sends.\n //\n // For facts about the caller that are true for the whole process rather than\n // for one event: which product is embedding the runtime, for instance. A\n // distribution built on top of this can then be told apart in the existing\n // events instead of sending its own, which is the difference between one\n // extra field and a second pipeline nobody asked for.\n //\n // Sent as `global_properties`, a field of its own, so these stay separable\n // from an event's own properties all the way to the sink.\n //\n // Do not reuse a key an event already sets: the fanout spreads this bag last\n // for `oss.runtime.*`, so a collision resolves in favour of the global and\n // does so silently. Names here should describe the caller, not the call.\n private globalProperties: Record<string, unknown> = {};\n\n constructor({\n telemetryDisabled,\n sampleRate,\n }: {\n telemetryDisabled?: boolean;\n sampleRate?: number;\n } = {}) {\n this.telemetryDisabled = telemetryDisabled ?? isTelemetryDisabled();\n this.setSampleRate(sampleRate);\n }\n\n private shouldSendEvent() {\n if (this.sampleRate >= 1) return true;\n return Math.random() < this.sampleRate;\n }\n\n /**\n * Add properties carried by every subsequent event.\n *\n * Merged rather than replaced, so two callers setting different fields do not\n * erase each other. Set once at runtime construction in practice; nothing\n * here is per-request.\n */\n setGlobalProperties(properties: Record<string, unknown>) {\n this.globalProperties = { ...this.globalProperties, ...properties };\n }\n\n setLicenseToken(licenseToken: string) {\n this.licenseToken = licenseToken;\n this.telemetryId = parseAndWarnTelemetryId(licenseToken);\n }\n\n async capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) {\n if (this.telemetryDisabled) return;\n // Anonymous callers are gated by sampleRate; identified callers\n // (telemetry_id present) bypass the gate and always send.\n if (!this.telemetryId && !this.shouldSendEvent()) return;\n\n await lambdaClient.send({\n event,\n properties: properties as Record<string, unknown>,\n // Its own field on the wire rather than folded into `properties`, which\n // is what the sink expects: for `oss.runtime.*` the fanout treats\n // `global_properties` as the SDK's pass-through bag and spreads it into\n // the analytics event, and v1's client sends package name and version the\n // same way. Folding it in would work and would put a process-level fact\n // in the per-event slot, where nothing downstream expects to find one.\n globalProperties: this.globalProperties,\n packageName: packageJson.name,\n packageVersion: packageJson.version,\n licenseToken: this.licenseToken ?? undefined,\n });\n }\n\n private setSampleRate(sampleRate: number | undefined) {\n let _sampleRate: number;\n\n _sampleRate = sampleRate ?? 0.05;\n\n if (process.env.COPILOTKIT_TELEMETRY_SAMPLE_RATE) {\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.\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 }\n}\n\nconst telemetry = new TelemetryClient();\nexport default telemetry;\n"],"mappings":";;;;;;;AAIA,SAAgBA,wBAA+B;AAC7C,QACG,QAAQ,IACN,kCAAkC,UACpC,QAAQ,IACN,kCAAkC,OACpC,QAAQ,IAA2C,iBAClD,UACD,QAAQ,IAA2C,iBAAiB;;AAIzE,IAAaC,oBAAb,MAA6B;CAiC3B,YAAY,EACV,mBACA,eAIE,EAAE,EAAE;2BAtC6B;oBAKR;sBAKS;qBAKD;0BAee,EAAE;AASpD,OAAK,oBAAoB,qBAAqBD,uBAAqB;AACnE,OAAK,cAAc,WAAW;;CAGhC,AAAQ,kBAAkB;AACxB,MAAI,KAAK,cAAc,EAAG,QAAO;AACjC,SAAO,KAAK,QAAQ,GAAG,KAAK;;;;;;;;;CAU9B,oBAAoB,YAAqC;AACvD,OAAK,mBAAmB;GAAE,GAAG,KAAK;GAAkB,GAAG;GAAY;;CAGrE,gBAAgB,cAAsB;AACpC,OAAK,eAAe;AACpB,OAAK,cAAc,wBAAwB,aAAa;;CAG1D,MAAM,QACJ,OACA,YACA;AACA,MAAI,KAAK,kBAAmB;AAG5B,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,iBAAiB,CAAE;AAElD,QAAM,aAAa,KAAK;GACtB;GACY;GAOZ,kBAAkB,KAAK;GACvB,aAAaE,eAAY;GACzB,gBAAgBA,eAAY;GAC5B,cAAc,KAAK,gBAAgB;GACpC,CAAC;;CAGJ,AAAQ,cAAc,YAAgC;EACpD,IAAI;AAEJ,gBAAc,cAAc;AAE5B,MAAI,QAAQ,IAAI,iCACd,eAAc,WAAW,QAAQ,IAAI,iCAAiC;AAMxE,MAAI,OAAO,MAAM,YAAY,IAAI,cAAc,KAAK,cAAc,EAChE,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAK,aAAa;;;AAItB,MAAM,YAAY,IAAID,mBAAiB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/runtime",
3
- "version": "1.68.3-canary.1787220377",
3
+ "version": "1.68.3",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "ai",
@@ -78,7 +78,6 @@
78
78
  "@ai-sdk/mcp": "^1.0.21",
79
79
  "@ai-sdk/openai": "^3.0.36",
80
80
  "@copilotkit/license-verifier": "~0.5.0",
81
- "@copilotkit/shared": "1.68.3-canary.1787220377",
82
81
  "@graphql-yoga/plugin-defer-stream": "^3.3.1",
83
82
  "@hono/node-server": "^1.13.5",
84
83
  "@modelcontextprotocol/sdk": "^1.18.2",
@@ -107,7 +106,8 @@
107
106
  "ws": "^8.18.0",
108
107
  "zod": "^3.23.3",
109
108
  "@copilotkit/channels-core": "^0.9.0",
110
- "@copilotkit/channels-intelligence": "0.9.0"
109
+ "@copilotkit/channels-intelligence": "0.9.0",
110
+ "@copilotkit/shared": "1.68.3"
111
111
  },
112
112
  "devDependencies": {
113
113
  "@copilotkit/aimock": "latest",
@@ -11,7 +11,7 @@ description: >
11
11
  discouraged. Load the reference under references/ that matches your task.
12
12
  type: core
13
13
  library: copilotkit
14
- library_version: "1.68.2"
14
+ library_version: "1.68.3"
15
15
  requires: []
16
16
  sources:
17
17
  - "CopilotKit/CopilotKit:packages/runtime/src/v2/runtime/core/fetch-handler.ts"