@copilotkit/shared 1.69.2 → 1.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +33 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -17
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +20 -17
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +30 -15
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +170 -31
- package/dist/index.umd.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/telemetry/index.d.mts +3 -2
- package/dist/telemetry/lambda-client.cjs +25 -4
- package/dist/telemetry/lambda-client.cjs.map +1 -1
- package/dist/telemetry/lambda-client.d.cts +14 -1
- package/dist/telemetry/lambda-client.d.cts.map +1 -1
- package/dist/telemetry/lambda-client.d.mts +14 -1
- package/dist/telemetry/lambda-client.d.mts.map +1 -1
- package/dist/telemetry/lambda-client.mjs +25 -5
- package/dist/telemetry/lambda-client.mjs.map +1 -1
- package/dist/telemetry/sampling.cjs +28 -0
- package/dist/telemetry/sampling.cjs.map +1 -0
- package/dist/telemetry/sampling.d.cts +37 -0
- package/dist/telemetry/sampling.d.cts.map +1 -0
- package/dist/telemetry/sampling.d.mts +37 -0
- package/dist/telemetry/sampling.d.mts.map +1 -0
- package/dist/telemetry/sampling.mjs +25 -0
- package/dist/telemetry/sampling.mjs.map +1 -0
- package/dist/telemetry/telemetry-client.cjs +72 -11
- package/dist/telemetry/telemetry-client.cjs.map +1 -1
- package/dist/telemetry/telemetry-client.d.cts +43 -1
- package/dist/telemetry/telemetry-client.d.cts.map +1 -1
- package/dist/telemetry/telemetry-client.d.mts +43 -1
- package/dist/telemetry/telemetry-client.d.mts.map +1 -1
- package/dist/telemetry/telemetry-client.mjs +73 -12
- package/dist/telemetry/telemetry-client.mjs.map +1 -1
- package/dist/utils/index.cjs +1 -0
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +2 -1
- package/dist/utils/index.d.cts.map +1 -1
- package/dist/utils/index.d.mts +2 -1
- package/dist/utils/index.d.mts.map +1 -1
- package/dist/utils/index.mjs +1 -0
- package/dist/utils/index.mjs.map +1 -1
- package/dist/utils/inspector-visibility.cjs +13 -0
- package/dist/utils/inspector-visibility.cjs.map +1 -0
- package/dist/utils/inspector-visibility.d.cts +18 -0
- package/dist/utils/inspector-visibility.d.cts.map +1 -0
- package/dist/utils/inspector-visibility.d.mts +18 -0
- package/dist/utils/inspector-visibility.d.mts.map +1 -0
- package/dist/utils/inspector-visibility.mjs +12 -0
- package/dist/utils/inspector-visibility.mjs.map +1 -0
- package/dist/utils/types.cjs.map +1 -1
- package/dist/utils/types.d.cts +46 -1
- package/dist/utils/types.d.cts.map +1 -1
- package/dist/utils/types.d.mts +46 -1
- package/dist/utils/types.d.mts.map +1 -1
- package/dist/utils/types.mjs.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/license-context.test.ts +224 -25
- package/src/index.ts +72 -16
- package/src/telemetry/index.ts +2 -0
- package/src/telemetry/lambda-client.test.ts +336 -1
- package/src/telemetry/lambda-client.ts +56 -15
- package/src/telemetry/sampling.test.ts +65 -0
- package/src/telemetry/sampling.ts +70 -0
- package/src/telemetry/telemetry-blank-license-identity.test.ts +121 -0
- package/src/telemetry/telemetry-client.test.ts +438 -15
- package/src/telemetry/telemetry-client.ts +145 -30
- package/src/utils/__tests__/conditions.test.ts +161 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/inspector-visibility.test.ts +43 -0
- package/src/utils/inspector-visibility.ts +17 -0
- package/src/utils/types.ts +52 -0
|
@@ -1 +1 @@
|
|
|
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: Record<string, any> = {\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,uBAA4C;GAChD,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,mCAAa,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"}
|
|
1
|
+
{"version":3,"file":"telemetry-client.cjs","names":["Analytics","computeSamplingMeta","TELEMETRY_EMITTER_V1","flattenObject","lambdaClient","firstNonBlankTelemetryId","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 {\n firstNonBlankTelemetryId,\n lambdaClient,\n parseAndWarnTelemetryId,\n} from \"./lambda-client\";\nimport { computeSamplingMeta, TELEMETRY_EMITTER_V1 } from \"./sampling\";\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\n/** Transport identity and sampling authority resolved for one runtime. */\nexport interface TelemetryIdentity {\n telemetryId?: string;\n licenseToken?: string;\n}\n\n/** Capture-only telemetry client bound to one runtime identity. */\nexport interface TelemetryCapture {\n capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void>;\n}\n\ninterface ResolvedTelemetryIdentity {\n telemetryId: string | null;\n licenseToken: string | null;\n licenseTelemetryId: string | null;\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 // Standalone analytics identity. This stays separate from the effective\n // identity so legacy callers continue sending only their license token to\n // the Lambda transport.\n private telemetryId: string | null = null;\n // License-derived identity used only as sampling authority. A standalone\n // telemetry id remains a transport claim and does not bypass sampleRate.\n private licenseTelemetryId: 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 ): Promise<void> {\n return this.captureWithIdentity(event, properties, {\n telemetryId: this.telemetryId,\n licenseToken: this.licenseToken,\n licenseTelemetryId: this.licenseTelemetryId,\n });\n }\n\n private async captureWithIdentity<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n identity: ResolvedTelemetryIdentity,\n ): Promise<void> {\n if (this.telemetryDisabled) {\n return;\n }\n\n // Callers without license-derived sampling authority are gated by\n // sampleRate. Legacy license tokens 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 (!identity.licenseTelemetryId && !this.shouldSendEvent()) {\n return;\n }\n\n // Sampling metadata is computed in ./sampling so this client and the\n // v2 runtime client can't drift apart again — see the note there.\n const samplingMeta = computeSamplingMeta({\n telemetryId: identity.licenseTelemetryId,\n sampleRate: this.sampleRate,\n });\n\n // Everything below travels identically on both copies of this event.\n // The event id is what makes the dual-write dedupable downstream:\n // one capture() produces one id, stamped on the lambda copy and the\n // Segment copy alike, so consumers no longer have to infer the\n // duplication from $lib or from which fields happen to be present\n // (OSS-1019).\n const eventMeta = {\n ...samplingMeta,\n telemetry_emitter: TELEMETRY_EMITTER_V1,\n telemetry_event_id: uuidv4(),\n };\n\n const flattenedProperties = flattenObject(properties);\n const propertiesWithGlobal: Record<string, any> = {\n ...this.globalProperties,\n ...eventMeta,\n telemetry_transport: \"segment\",\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: {\n ...this.globalProperties,\n ...eventMeta,\n telemetry_transport: \"lambda\",\n },\n packageName: this.packageName,\n packageVersion: this.packageVersion,\n telemetryId: identity.telemetryId ?? undefined,\n licenseToken: identity.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 /**\n * Atomically configure standalone, legacy, or anonymous telemetry identity.\n *\n * A standalone id takes transport precedence over a supplied legacy license\n * token, but only a license-derived id grants sampling authority. Neither\n * value is added to event properties.\n *\n * @param identity - One standalone id, one legacy license token, or neither.\n */\n setTelemetryIdentity(identity: {\n telemetryId?: string;\n licenseToken?: string;\n }): void {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n this.telemetryId = resolvedIdentity.telemetryId;\n this.licenseToken = resolvedIdentity.licenseToken;\n this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;\n }\n\n /**\n * Configure legacy license-derived telemetry identity.\n *\n * @param licenseToken - License token whose telemetry claim identifies sends.\n */\n setLicenseToken(licenseToken: string) {\n this.setTelemetryIdentity({ licenseToken });\n }\n\n /**\n * Create an immutable capture scope for one runtime.\n *\n * The scope shares this client's sinks, process-wide opt-out, global\n * properties, and sampling settings, but snapshots transport identity and\n * license-derived sampling authority. Constructing another runtime cannot\n * rewrite an existing scope.\n *\n * @param identity - The runtime's construction-time telemetry identity.\n * @returns A capture-only client bound to that identity.\n */\n createScope(identity: TelemetryIdentity): TelemetryCapture {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n\n return {\n capture: <K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) => this.captureWithIdentity(event, properties, resolvedIdentity),\n };\n }\n\n private resolveTelemetryIdentity(\n identity: TelemetryIdentity,\n ): ResolvedTelemetryIdentity {\n const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);\n if (telemetryId !== undefined) {\n return {\n telemetryId,\n licenseToken: null,\n licenseTelemetryId: null,\n };\n }\n\n return {\n telemetryId: null,\n licenseToken: identity.licenseToken ?? null,\n licenseTelemetryId: identity.licenseToken\n ? parseAndWarnTelemetryId(identity.licenseToken)\n : null,\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 // 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 per capture() in ./sampling. Only license-\n // authorized events get effectiveSampleRate=1; standalone transport\n // identity stays in the sampled population.\n }\n}\n"],"mappings":"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"}
|
|
@@ -9,6 +9,15 @@ import { Analytics } from "@segment/analytics-node";
|
|
|
9
9
|
* - DO_NOT_TRACK=true or DO_NOT_TRACK=1
|
|
10
10
|
*/
|
|
11
11
|
declare function isTelemetryDisabled(): boolean;
|
|
12
|
+
/** Transport identity and sampling authority resolved for one runtime. */
|
|
13
|
+
interface TelemetryIdentity {
|
|
14
|
+
telemetryId?: string;
|
|
15
|
+
licenseToken?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Capture-only telemetry client bound to one runtime identity. */
|
|
18
|
+
interface TelemetryCapture {
|
|
19
|
+
capture<K extends keyof AnalyticsEvents>(event: K, properties: AnalyticsEvents[K]): Promise<void>;
|
|
20
|
+
}
|
|
12
21
|
declare class TelemetryClient {
|
|
13
22
|
segment: Analytics | undefined;
|
|
14
23
|
globalProperties: Record<string, any>;
|
|
@@ -18,6 +27,7 @@ declare class TelemetryClient {
|
|
|
18
27
|
} | null;
|
|
19
28
|
private licenseToken;
|
|
20
29
|
private telemetryId;
|
|
30
|
+
private licenseTelemetryId;
|
|
21
31
|
packageName: string;
|
|
22
32
|
packageVersion: string;
|
|
23
33
|
private telemetryDisabled;
|
|
@@ -38,14 +48,46 @@ declare class TelemetryClient {
|
|
|
38
48
|
});
|
|
39
49
|
private shouldSendEvent;
|
|
40
50
|
capture<K extends keyof AnalyticsEvents>(event: K, properties: AnalyticsEvents[K]): Promise<void>;
|
|
51
|
+
private captureWithIdentity;
|
|
41
52
|
setGlobalProperties(properties: Record<string, any>): void;
|
|
42
53
|
setCloudConfiguration(properties: {
|
|
43
54
|
publicApiKey: string;
|
|
44
55
|
baseUrl: string;
|
|
45
56
|
}): void;
|
|
57
|
+
/**
|
|
58
|
+
* Atomically configure standalone, legacy, or anonymous telemetry identity.
|
|
59
|
+
*
|
|
60
|
+
* A standalone id takes transport precedence over a supplied legacy license
|
|
61
|
+
* token, but only a license-derived id grants sampling authority. Neither
|
|
62
|
+
* value is added to event properties.
|
|
63
|
+
*
|
|
64
|
+
* @param identity - One standalone id, one legacy license token, or neither.
|
|
65
|
+
*/
|
|
66
|
+
setTelemetryIdentity(identity: {
|
|
67
|
+
telemetryId?: string;
|
|
68
|
+
licenseToken?: string;
|
|
69
|
+
}): void;
|
|
70
|
+
/**
|
|
71
|
+
* Configure legacy license-derived telemetry identity.
|
|
72
|
+
*
|
|
73
|
+
* @param licenseToken - License token whose telemetry claim identifies sends.
|
|
74
|
+
*/
|
|
46
75
|
setLicenseToken(licenseToken: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Create an immutable capture scope for one runtime.
|
|
78
|
+
*
|
|
79
|
+
* The scope shares this client's sinks, process-wide opt-out, global
|
|
80
|
+
* properties, and sampling settings, but snapshots transport identity and
|
|
81
|
+
* license-derived sampling authority. Constructing another runtime cannot
|
|
82
|
+
* rewrite an existing scope.
|
|
83
|
+
*
|
|
84
|
+
* @param identity - The runtime's construction-time telemetry identity.
|
|
85
|
+
* @returns A capture-only client bound to that identity.
|
|
86
|
+
*/
|
|
87
|
+
createScope(identity: TelemetryIdentity): TelemetryCapture;
|
|
88
|
+
private resolveTelemetryIdentity;
|
|
47
89
|
private setSampleRate;
|
|
48
90
|
}
|
|
49
91
|
//#endregion
|
|
50
|
-
export { TelemetryClient, isTelemetryDisabled };
|
|
92
|
+
export { TelemetryCapture, TelemetryClient, TelemetryIdentity, isTelemetryDisabled };
|
|
51
93
|
//# sourceMappingURL=telemetry-client.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-client.d.cts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"telemetry-client.d.cts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;AAiBA;;;;iBAAgB,mBAAA,CAAA;AAahB;AAAA,UAAiB,iBAAA;EACf,WAAA;EACA,YAAA;AAAA;AAIF;AAAA,UAAiB,gBAAA;EACf,OAAA,iBAAwB,eAAA,EACtB,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAC3B,OAAA;AAAA;AAAA,cASQ,eAAA;EACX,OAAA,EAAS,SAAA;EACT,gBAAA,EAAkB,MAAA;EAClB,kBAAA;IAAsB,YAAA;IAAsB,OAAA;EAAA;EAAA,QAIpC,YAAA;EAAA,QAIA,WAAA;EAAA,QAGA,kBAAA;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,IAC3B,OAAA;EAAA,QAQW,mBAAA;EA4Ed,mBAAA,CAAoB,UAAA,EAAY,MAAA;EAQhC,qBAAA,CAAsB,UAAA;IAAc,YAAA;IAAsB,OAAA;EAAA;EA7F5B;;;;;;;;;EAiH9B,oBAAA,CAAqB,QAAA;IACnB,WAAA;IACA,YAAA;EAAA;EAtL0C;;;;;EAmM5C,eAAA,CAAgB,YAAA;EArLR;;;;;;;;;;;EAoMR,WAAA,CAAY,QAAA,EAAU,iBAAA,GAAoB,gBAAA;EAAA,QAWlC,wBAAA;EAAA,QAqBA,aAAA;AAAA"}
|
|
@@ -9,6 +9,15 @@ import { Analytics } from "@segment/analytics-node";
|
|
|
9
9
|
* - DO_NOT_TRACK=true or DO_NOT_TRACK=1
|
|
10
10
|
*/
|
|
11
11
|
declare function isTelemetryDisabled(): boolean;
|
|
12
|
+
/** Transport identity and sampling authority resolved for one runtime. */
|
|
13
|
+
interface TelemetryIdentity {
|
|
14
|
+
telemetryId?: string;
|
|
15
|
+
licenseToken?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Capture-only telemetry client bound to one runtime identity. */
|
|
18
|
+
interface TelemetryCapture {
|
|
19
|
+
capture<K extends keyof AnalyticsEvents>(event: K, properties: AnalyticsEvents[K]): Promise<void>;
|
|
20
|
+
}
|
|
12
21
|
declare class TelemetryClient {
|
|
13
22
|
segment: Analytics | undefined;
|
|
14
23
|
globalProperties: Record<string, any>;
|
|
@@ -18,6 +27,7 @@ declare class TelemetryClient {
|
|
|
18
27
|
} | null;
|
|
19
28
|
private licenseToken;
|
|
20
29
|
private telemetryId;
|
|
30
|
+
private licenseTelemetryId;
|
|
21
31
|
packageName: string;
|
|
22
32
|
packageVersion: string;
|
|
23
33
|
private telemetryDisabled;
|
|
@@ -38,14 +48,46 @@ declare class TelemetryClient {
|
|
|
38
48
|
});
|
|
39
49
|
private shouldSendEvent;
|
|
40
50
|
capture<K extends keyof AnalyticsEvents>(event: K, properties: AnalyticsEvents[K]): Promise<void>;
|
|
51
|
+
private captureWithIdentity;
|
|
41
52
|
setGlobalProperties(properties: Record<string, any>): void;
|
|
42
53
|
setCloudConfiguration(properties: {
|
|
43
54
|
publicApiKey: string;
|
|
44
55
|
baseUrl: string;
|
|
45
56
|
}): void;
|
|
57
|
+
/**
|
|
58
|
+
* Atomically configure standalone, legacy, or anonymous telemetry identity.
|
|
59
|
+
*
|
|
60
|
+
* A standalone id takes transport precedence over a supplied legacy license
|
|
61
|
+
* token, but only a license-derived id grants sampling authority. Neither
|
|
62
|
+
* value is added to event properties.
|
|
63
|
+
*
|
|
64
|
+
* @param identity - One standalone id, one legacy license token, or neither.
|
|
65
|
+
*/
|
|
66
|
+
setTelemetryIdentity(identity: {
|
|
67
|
+
telemetryId?: string;
|
|
68
|
+
licenseToken?: string;
|
|
69
|
+
}): void;
|
|
70
|
+
/**
|
|
71
|
+
* Configure legacy license-derived telemetry identity.
|
|
72
|
+
*
|
|
73
|
+
* @param licenseToken - License token whose telemetry claim identifies sends.
|
|
74
|
+
*/
|
|
46
75
|
setLicenseToken(licenseToken: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Create an immutable capture scope for one runtime.
|
|
78
|
+
*
|
|
79
|
+
* The scope shares this client's sinks, process-wide opt-out, global
|
|
80
|
+
* properties, and sampling settings, but snapshots transport identity and
|
|
81
|
+
* license-derived sampling authority. Constructing another runtime cannot
|
|
82
|
+
* rewrite an existing scope.
|
|
83
|
+
*
|
|
84
|
+
* @param identity - The runtime's construction-time telemetry identity.
|
|
85
|
+
* @returns A capture-only client bound to that identity.
|
|
86
|
+
*/
|
|
87
|
+
createScope(identity: TelemetryIdentity): TelemetryCapture;
|
|
88
|
+
private resolveTelemetryIdentity;
|
|
47
89
|
private setSampleRate;
|
|
48
90
|
}
|
|
49
91
|
//#endregion
|
|
50
|
-
export { TelemetryClient, isTelemetryDisabled };
|
|
92
|
+
export { TelemetryCapture, TelemetryClient, TelemetryIdentity, isTelemetryDisabled };
|
|
51
93
|
//# sourceMappingURL=telemetry-client.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-client.d.mts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"telemetry-client.d.mts","names":[],"sources":["../../src/telemetry/telemetry-client.ts"],"mappings":";;;;;;AAiBA;;;;iBAAgB,mBAAA,CAAA;AAahB;AAAA,UAAiB,iBAAA;EACf,WAAA;EACA,YAAA;AAAA;AAIF;AAAA,UAAiB,gBAAA;EACf,OAAA,iBAAwB,eAAA,EACtB,KAAA,EAAO,CAAA,EACP,UAAA,EAAY,eAAA,CAAgB,CAAA,IAC3B,OAAA;AAAA;AAAA,cASQ,eAAA;EACX,OAAA,EAAS,SAAA;EACT,gBAAA,EAAkB,MAAA;EAClB,kBAAA;IAAsB,YAAA;IAAsB,OAAA;EAAA;EAAA,QAIpC,YAAA;EAAA,QAIA,WAAA;EAAA,QAGA,kBAAA;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,IAC3B,OAAA;EAAA,QAQW,mBAAA;EA4Ed,mBAAA,CAAoB,UAAA,EAAY,MAAA;EAQhC,qBAAA,CAAsB,UAAA;IAAc,YAAA;IAAsB,OAAA;EAAA;EA7F5B;;;;;;;;;EAiH9B,oBAAA,CAAqB,QAAA;IACnB,WAAA;IACA,YAAA;EAAA;EAtL0C;;;;;EAmM5C,eAAA,CAAgB,YAAA;EArLR;;;;;;;;;;;EAoMR,WAAA,CAAY,QAAA,EAAU,iBAAA,GAAoB,gBAAA;EAAA,QAWlC,wBAAA;EAAA,QAqBA,aAAA;AAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { flattenObject } from "./utils.mjs";
|
|
2
|
-
import { lambdaClient, parseAndWarnTelemetryId } from "./lambda-client.mjs";
|
|
2
|
+
import { firstNonBlankTelemetryId, lambdaClient, parseAndWarnTelemetryId } from "./lambda-client.mjs";
|
|
3
|
+
import { TELEMETRY_EMITTER_V1, computeSamplingMeta } from "./sampling.mjs";
|
|
3
4
|
import { v4 } from "uuid";
|
|
4
5
|
import { Analytics } from "@segment/analytics-node";
|
|
5
6
|
|
|
@@ -19,6 +20,7 @@ var TelemetryClient = class {
|
|
|
19
20
|
this.cloudConfiguration = null;
|
|
20
21
|
this.licenseToken = null;
|
|
21
22
|
this.telemetryId = null;
|
|
23
|
+
this.licenseTelemetryId = null;
|
|
22
24
|
this.telemetryDisabled = false;
|
|
23
25
|
this.sampleRate = .05;
|
|
24
26
|
this.anonymousId = `anon_${v4()}`;
|
|
@@ -37,18 +39,28 @@ var TelemetryClient = class {
|
|
|
37
39
|
return Math.random() < this.sampleRate;
|
|
38
40
|
}
|
|
39
41
|
async capture(event, properties) {
|
|
42
|
+
return this.captureWithIdentity(event, properties, {
|
|
43
|
+
telemetryId: this.telemetryId,
|
|
44
|
+
licenseToken: this.licenseToken,
|
|
45
|
+
licenseTelemetryId: this.licenseTelemetryId
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async captureWithIdentity(event, properties, identity) {
|
|
40
49
|
if (this.telemetryDisabled) return;
|
|
41
|
-
if (!
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
if (!identity.licenseTelemetryId && !this.shouldSendEvent()) return;
|
|
51
|
+
const eventMeta = {
|
|
52
|
+
...computeSamplingMeta({
|
|
53
|
+
telemetryId: identity.licenseTelemetryId,
|
|
54
|
+
sampleRate: this.sampleRate
|
|
55
|
+
}),
|
|
56
|
+
telemetry_emitter: TELEMETRY_EMITTER_V1,
|
|
57
|
+
telemetry_event_id: v4()
|
|
47
58
|
};
|
|
48
59
|
const flattenedProperties = flattenObject(properties);
|
|
49
60
|
const propertiesWithGlobal = {
|
|
50
61
|
...this.globalProperties,
|
|
51
|
-
...
|
|
62
|
+
...eventMeta,
|
|
63
|
+
telemetry_transport: "segment",
|
|
52
64
|
...flattenedProperties
|
|
53
65
|
};
|
|
54
66
|
const orderedPropertiesWithGlobal = Object.keys(propertiesWithGlobal).sort().reduce((obj, key) => {
|
|
@@ -60,11 +72,13 @@ var TelemetryClient = class {
|
|
|
60
72
|
properties: flattenedProperties,
|
|
61
73
|
globalProperties: {
|
|
62
74
|
...this.globalProperties,
|
|
63
|
-
...
|
|
75
|
+
...eventMeta,
|
|
76
|
+
telemetry_transport: "lambda"
|
|
64
77
|
},
|
|
65
78
|
packageName: this.packageName,
|
|
66
79
|
packageVersion: this.packageVersion,
|
|
67
|
-
|
|
80
|
+
telemetryId: identity.telemetryId ?? void 0,
|
|
81
|
+
licenseToken: identity.licenseToken ?? void 0
|
|
68
82
|
});
|
|
69
83
|
if (this.segment) this.segment.track({
|
|
70
84
|
anonymousId: this.anonymousId,
|
|
@@ -86,9 +100,56 @@ var TelemetryClient = class {
|
|
|
86
100
|
baseUrl: properties.baseUrl
|
|
87
101
|
} });
|
|
88
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Atomically configure standalone, legacy, or anonymous telemetry identity.
|
|
105
|
+
*
|
|
106
|
+
* A standalone id takes transport precedence over a supplied legacy license
|
|
107
|
+
* token, but only a license-derived id grants sampling authority. Neither
|
|
108
|
+
* value is added to event properties.
|
|
109
|
+
*
|
|
110
|
+
* @param identity - One standalone id, one legacy license token, or neither.
|
|
111
|
+
*/
|
|
112
|
+
setTelemetryIdentity(identity) {
|
|
113
|
+
const resolvedIdentity = this.resolveTelemetryIdentity(identity);
|
|
114
|
+
this.telemetryId = resolvedIdentity.telemetryId;
|
|
115
|
+
this.licenseToken = resolvedIdentity.licenseToken;
|
|
116
|
+
this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Configure legacy license-derived telemetry identity.
|
|
120
|
+
*
|
|
121
|
+
* @param licenseToken - License token whose telemetry claim identifies sends.
|
|
122
|
+
*/
|
|
89
123
|
setLicenseToken(licenseToken) {
|
|
90
|
-
this.licenseToken
|
|
91
|
-
|
|
124
|
+
this.setTelemetryIdentity({ licenseToken });
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Create an immutable capture scope for one runtime.
|
|
128
|
+
*
|
|
129
|
+
* The scope shares this client's sinks, process-wide opt-out, global
|
|
130
|
+
* properties, and sampling settings, but snapshots transport identity and
|
|
131
|
+
* license-derived sampling authority. Constructing another runtime cannot
|
|
132
|
+
* rewrite an existing scope.
|
|
133
|
+
*
|
|
134
|
+
* @param identity - The runtime's construction-time telemetry identity.
|
|
135
|
+
* @returns A capture-only client bound to that identity.
|
|
136
|
+
*/
|
|
137
|
+
createScope(identity) {
|
|
138
|
+
const resolvedIdentity = this.resolveTelemetryIdentity(identity);
|
|
139
|
+
return { capture: (event, properties) => this.captureWithIdentity(event, properties, resolvedIdentity) };
|
|
140
|
+
}
|
|
141
|
+
resolveTelemetryIdentity(identity) {
|
|
142
|
+
const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);
|
|
143
|
+
if (telemetryId !== void 0) return {
|
|
144
|
+
telemetryId,
|
|
145
|
+
licenseToken: null,
|
|
146
|
+
licenseTelemetryId: null
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
telemetryId: null,
|
|
150
|
+
licenseToken: identity.licenseToken ?? null,
|
|
151
|
+
licenseTelemetryId: identity.licenseToken ? parseAndWarnTelemetryId(identity.licenseToken) : null
|
|
152
|
+
};
|
|
92
153
|
}
|
|
93
154
|
setSampleRate(sampleRate) {
|
|
94
155
|
let _sampleRate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-client.mjs","names":["uuidv4"],"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: Record<string, any> = {\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,uBAA4C;GAChD,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,QAAM,aAAa,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"}
|
|
1
|
+
{"version":3,"file":"telemetry-client.mjs","names":["uuidv4"],"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 {\n firstNonBlankTelemetryId,\n lambdaClient,\n parseAndWarnTelemetryId,\n} from \"./lambda-client\";\nimport { computeSamplingMeta, TELEMETRY_EMITTER_V1 } from \"./sampling\";\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\n/** Transport identity and sampling authority resolved for one runtime. */\nexport interface TelemetryIdentity {\n telemetryId?: string;\n licenseToken?: string;\n}\n\n/** Capture-only telemetry client bound to one runtime identity. */\nexport interface TelemetryCapture {\n capture<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ): Promise<void>;\n}\n\ninterface ResolvedTelemetryIdentity {\n telemetryId: string | null;\n licenseToken: string | null;\n licenseTelemetryId: string | null;\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 // Standalone analytics identity. This stays separate from the effective\n // identity so legacy callers continue sending only their license token to\n // the Lambda transport.\n private telemetryId: string | null = null;\n // License-derived identity used only as sampling authority. A standalone\n // telemetry id remains a transport claim and does not bypass sampleRate.\n private licenseTelemetryId: 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 ): Promise<void> {\n return this.captureWithIdentity(event, properties, {\n telemetryId: this.telemetryId,\n licenseToken: this.licenseToken,\n licenseTelemetryId: this.licenseTelemetryId,\n });\n }\n\n private async captureWithIdentity<K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n identity: ResolvedTelemetryIdentity,\n ): Promise<void> {\n if (this.telemetryDisabled) {\n return;\n }\n\n // Callers without license-derived sampling authority are gated by\n // sampleRate. Legacy license tokens 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 (!identity.licenseTelemetryId && !this.shouldSendEvent()) {\n return;\n }\n\n // Sampling metadata is computed in ./sampling so this client and the\n // v2 runtime client can't drift apart again — see the note there.\n const samplingMeta = computeSamplingMeta({\n telemetryId: identity.licenseTelemetryId,\n sampleRate: this.sampleRate,\n });\n\n // Everything below travels identically on both copies of this event.\n // The event id is what makes the dual-write dedupable downstream:\n // one capture() produces one id, stamped on the lambda copy and the\n // Segment copy alike, so consumers no longer have to infer the\n // duplication from $lib or from which fields happen to be present\n // (OSS-1019).\n const eventMeta = {\n ...samplingMeta,\n telemetry_emitter: TELEMETRY_EMITTER_V1,\n telemetry_event_id: uuidv4(),\n };\n\n const flattenedProperties = flattenObject(properties);\n const propertiesWithGlobal: Record<string, any> = {\n ...this.globalProperties,\n ...eventMeta,\n telemetry_transport: \"segment\",\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: {\n ...this.globalProperties,\n ...eventMeta,\n telemetry_transport: \"lambda\",\n },\n packageName: this.packageName,\n packageVersion: this.packageVersion,\n telemetryId: identity.telemetryId ?? undefined,\n licenseToken: identity.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 /**\n * Atomically configure standalone, legacy, or anonymous telemetry identity.\n *\n * A standalone id takes transport precedence over a supplied legacy license\n * token, but only a license-derived id grants sampling authority. Neither\n * value is added to event properties.\n *\n * @param identity - One standalone id, one legacy license token, or neither.\n */\n setTelemetryIdentity(identity: {\n telemetryId?: string;\n licenseToken?: string;\n }): void {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n this.telemetryId = resolvedIdentity.telemetryId;\n this.licenseToken = resolvedIdentity.licenseToken;\n this.licenseTelemetryId = resolvedIdentity.licenseTelemetryId;\n }\n\n /**\n * Configure legacy license-derived telemetry identity.\n *\n * @param licenseToken - License token whose telemetry claim identifies sends.\n */\n setLicenseToken(licenseToken: string) {\n this.setTelemetryIdentity({ licenseToken });\n }\n\n /**\n * Create an immutable capture scope for one runtime.\n *\n * The scope shares this client's sinks, process-wide opt-out, global\n * properties, and sampling settings, but snapshots transport identity and\n * license-derived sampling authority. Constructing another runtime cannot\n * rewrite an existing scope.\n *\n * @param identity - The runtime's construction-time telemetry identity.\n * @returns A capture-only client bound to that identity.\n */\n createScope(identity: TelemetryIdentity): TelemetryCapture {\n const resolvedIdentity = this.resolveTelemetryIdentity(identity);\n\n return {\n capture: <K extends keyof AnalyticsEvents>(\n event: K,\n properties: AnalyticsEvents[K],\n ) => this.captureWithIdentity(event, properties, resolvedIdentity),\n };\n }\n\n private resolveTelemetryIdentity(\n identity: TelemetryIdentity,\n ): ResolvedTelemetryIdentity {\n const telemetryId = firstNonBlankTelemetryId(identity.telemetryId);\n if (telemetryId !== undefined) {\n return {\n telemetryId,\n licenseToken: null,\n licenseTelemetryId: null,\n };\n }\n\n return {\n telemetryId: null,\n licenseToken: identity.licenseToken ?? null,\n licenseTelemetryId: identity.licenseToken\n ? parseAndWarnTelemetryId(identity.licenseToken)\n : null,\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 // 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 per capture() in ./sampling. Only license-\n // authorized events get effectiveSampleRate=1; standalone transport\n // identity stays in the sampled population.\n }\n}\n"],"mappings":"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"}
|
package/dist/utils/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ const require_console_styling = require('./console-styling.cjs');
|
|
|
5
5
|
const require_errors = require('./errors.cjs');
|
|
6
6
|
const require_json_schema = require('./json-schema.cjs');
|
|
7
7
|
const require_inspector_metadata = require('./inspector-metadata.cjs');
|
|
8
|
+
const require_inspector_visibility = require('./inspector-visibility.cjs');
|
|
8
9
|
const require_types = require('./types.cjs');
|
|
9
10
|
const require_random_id = require('./random-id.cjs');
|
|
10
11
|
const require_requests = require('./requests.cjs');
|
package/dist/utils/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["PartialJSON"],"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from \"./clipboard\";\nexport * from \"./conditions\";\nexport * from \"./console-styling\";\nexport * from \"./errors\";\nexport * from \"./json-schema\";\nexport * from \"./inspector-metadata\";\nexport * from \"./types\";\nexport * from \"./random-id\";\nexport * from \"./requests\";\n\nimport * as PartialJSON from \"partial-json\";\n\n/**\n * Safely parses a JSON string into an object\n * @param json The JSON string to parse\n * @param fallback Optional fallback value to return if parsing fails. If not provided or set to \"unset\", returns null\n * @returns The parsed JSON object, or the fallback value (or null) if parsing fails\n */\nexport function parseJson(json: string, fallback: any = \"unset\") {\n try {\n return JSON.parse(json);\n } catch {\n return fallback === \"unset\" ? null : fallback;\n }\n}\n\n/**\n * Parses a partial/incomplete JSON string, returning as much valid data as possible.\n * Falls back to an empty object if parsing fails entirely.\n */\nexport function partialJSONParse(json: string) {\n try {\n const parsed = PartialJSON.parse(json);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n}\n\n/**\n * Returns an exponential backoff function suitable for Phoenix.js\n * `reconnectAfterMs` and `rejoinAfterMs` options.\n *\n * @param baseMs - Initial delay for the first retry attempt.\n * @param maxMs - Upper bound — delays are capped at this value.\n *\n * Phoenix calls the returned function with a 1-based `tries` count.\n * The delay doubles on each attempt: baseMs, 2×baseMs, 4×baseMs, …, maxMs.\n */\nexport function phoenixExponentialBackoff(\n baseMs: number,\n maxMs: number,\n): (tries: number) => number {\n return (tries: number) => Math.min(baseMs * 2 ** (tries - 1), maxMs);\n}\n\n/**\n * Maps an array of items to a new array, skipping items that throw errors during mapping\n * @param items The array to map\n * @param callback The mapping function to apply to each item\n * @returns A new array containing only the successfully mapped items\n */\nexport function tryMap<TItem, TMapped>(\n items: TItem[],\n callback: (item: TItem, index: number, array: TItem[]) => TMapped,\n): TMapped[] {\n return items.reduce<TMapped[]>((acc, item, index, array) => {\n try {\n acc.push(callback(item, index, array));\n } catch (error) {\n console.error(error);\n }\n return acc;\n }, []);\n}\n\n/**\n * Checks if the current environment is macOS\n * @returns {boolean} True if running on macOS, false otherwise\n */\nexport function isMacOS(): boolean {\n return /Mac|iMac|Macintosh/i.test(navigator.userAgent);\n}\n\n/**\n * Safely parses a JSON string into a tool arguments object.\n * Returns the parsed object only if it's a plain object (not an array, null, etc.).\n * Falls back to an empty object for any non-object JSON value or parse failure.\n */\nexport function safeParseToolArgs(raw: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`,\n );\n return {};\n } catch {\n console.warn(\n \"[CopilotKit] Failed to parse tool arguments, falling back to empty object\",\n );\n return {};\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["PartialJSON"],"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from \"./clipboard\";\nexport * from \"./conditions\";\nexport * from \"./console-styling\";\nexport * from \"./errors\";\nexport * from \"./json-schema\";\nexport * from \"./inspector-metadata\";\nexport * from \"./inspector-visibility\";\nexport * from \"./types\";\nexport * from \"./random-id\";\nexport * from \"./requests\";\n\nimport * as PartialJSON from \"partial-json\";\n\n/**\n * Safely parses a JSON string into an object\n * @param json The JSON string to parse\n * @param fallback Optional fallback value to return if parsing fails. If not provided or set to \"unset\", returns null\n * @returns The parsed JSON object, or the fallback value (or null) if parsing fails\n */\nexport function parseJson(json: string, fallback: any = \"unset\") {\n try {\n return JSON.parse(json);\n } catch {\n return fallback === \"unset\" ? null : fallback;\n }\n}\n\n/**\n * Parses a partial/incomplete JSON string, returning as much valid data as possible.\n * Falls back to an empty object if parsing fails entirely.\n */\nexport function partialJSONParse(json: string) {\n try {\n const parsed = PartialJSON.parse(json);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n}\n\n/**\n * Returns an exponential backoff function suitable for Phoenix.js\n * `reconnectAfterMs` and `rejoinAfterMs` options.\n *\n * @param baseMs - Initial delay for the first retry attempt.\n * @param maxMs - Upper bound — delays are capped at this value.\n *\n * Phoenix calls the returned function with a 1-based `tries` count.\n * The delay doubles on each attempt: baseMs, 2×baseMs, 4×baseMs, …, maxMs.\n */\nexport function phoenixExponentialBackoff(\n baseMs: number,\n maxMs: number,\n): (tries: number) => number {\n return (tries: number) => Math.min(baseMs * 2 ** (tries - 1), maxMs);\n}\n\n/**\n * Maps an array of items to a new array, skipping items that throw errors during mapping\n * @param items The array to map\n * @param callback The mapping function to apply to each item\n * @returns A new array containing only the successfully mapped items\n */\nexport function tryMap<TItem, TMapped>(\n items: TItem[],\n callback: (item: TItem, index: number, array: TItem[]) => TMapped,\n): TMapped[] {\n return items.reduce<TMapped[]>((acc, item, index, array) => {\n try {\n acc.push(callback(item, index, array));\n } catch (error) {\n console.error(error);\n }\n return acc;\n }, []);\n}\n\n/**\n * Checks if the current environment is macOS\n * @returns {boolean} True if running on macOS, false otherwise\n */\nexport function isMacOS(): boolean {\n return /Mac|iMac|Macintosh/i.test(navigator.userAgent);\n}\n\n/**\n * Safely parses a JSON string into a tool arguments object.\n * Returns the parsed object only if it's a plain object (not an array, null, etc.).\n * Falls back to an empty object for any non-object JSON value or parse failure.\n */\nexport function safeParseToolArgs(raw: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`,\n );\n return {};\n } catch {\n console.warn(\n \"[CopilotKit] Failed to parse tool arguments, falling back to empty object\",\n );\n return {};\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,UAAU,MAAc,WAAgB,SAAS;AAC/D,KAAI;AACF,SAAO,KAAK,MAAM,KAAK;SACjB;AACN,SAAO,aAAa,UAAU,OAAO;;;;;;;AAQzC,SAAgB,iBAAiB,MAAc;AAC7C,KAAI;EACF,MAAM,SAASA,aAAY,MAAM,KAAK;AACtC,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAChE,QAAO;AAET,SAAO,EAAE;SACH;AACN,SAAO,EAAE;;;;;;;;;;;;;AAcb,SAAgB,0BACd,QACA,OAC2B;AAC3B,SAAQ,UAAkB,KAAK,IAAI,SAAS,MAAM,QAAQ,IAAI,MAAM;;;;;;;;AAStE,SAAgB,OACd,OACA,UACW;AACX,QAAO,MAAM,QAAmB,KAAK,MAAM,OAAO,UAAU;AAC1D,MAAI;AACF,OAAI,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC;WAC/B,OAAO;AACd,WAAQ,MAAM,MAAM;;AAEtB,SAAO;IACN,EAAE,CAAC;;;;;;AAOR,SAAgB,UAAmB;AACjC,QAAO,sBAAsB,KAAK,UAAU,UAAU;;;;;;;AAQxD,SAAgB,kBAAkB,KAAsC;AACtE,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAChE,QAAO;AAET,UAAQ,KACN,qDAAqD,OAAO,OAAO,iCACpE;AACD,SAAO,EAAE;SACH;AACN,UAAQ,KACN,4EACD;AACD,SAAO,EAAE"}
|
package/dist/utils/index.d.cts
CHANGED
|
@@ -4,7 +4,8 @@ import { ConsoleColors, ConsoleStyles, logCopilotKitPlatformMessage, logStyled,
|
|
|
4
4
|
import { BANNER_ERROR_NAMES, COPILOT_CLOUD_ERROR_NAMES, ConfigurationError, CopilotKitAgentDiscoveryError, CopilotKitApiDiscoveryError, CopilotKitError, CopilotKitErrorCode, CopilotKitLowLevelError, CopilotKitMisuseError, CopilotKitRemoteEndpointDiscoveryError, CopilotKitVersionMismatchError, ERROR_CONFIG, ERROR_NAMES, ErrorVisibility, MissingPublicApiKeyError, ResolvedCopilotKitError, Severity, UpgradeRequiredError, ensureStructuredError, getPossibleVersionMismatch, isStructuredCopilotKitError } from "./errors.cjs";
|
|
5
5
|
import { JSONSchema, JSONSchemaArray, JSONSchemaBoolean, JSONSchemaNumber, JSONSchemaObject, JSONSchemaString, actionParametersToJsonSchema, convertJsonSchemaToZodSchema, getZodParameters, jsonSchemaToActionParameters } from "./json-schema.cjs";
|
|
6
6
|
import { InspectorMetadataV1, parseInspectorMetadataV1 } from "./inspector-metadata.cjs";
|
|
7
|
-
import {
|
|
7
|
+
import { InspectorVisibilityOptions, shouldEnableInspector } from "./inspector-visibility.cjs";
|
|
8
|
+
import { A2UIRuntimeInfo, AgentDescription, IntelligenceRuntimeInfo, MaybePromise, NonEmptyRecord, RUNTIME_MODE_INTELLIGENCE, RUNTIME_MODE_SSE, RuntimeEntitlementResponse, RuntimeInfo, RuntimeLicenseStatus, RuntimeMode, ThreadEndpointRuntimeInfo } from "./types.cjs";
|
|
8
9
|
import { dataToUUID, isValidUUID, randomId, randomUUID } from "./random-id.cjs";
|
|
9
10
|
import { readBody } from "./requests.cjs";
|
|
10
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/utils/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/utils/index.ts"],"mappings":";;;;;;;;;;;;;;AAmBA;;;;iBAAgB,SAAA,CAAU,IAAA,UAAc,QAAA;AAYxC;;;;AAAA,iBAAgB,gBAAA,CAAiB,IAAA;AAsBjC;;;;;;;;;AAaA;AAbA,iBAAgB,yBAAA,CACd,MAAA,UACA,KAAA,YACE,KAAA;;;;;;;iBAUY,MAAA,gBAAA,CACd,KAAA,EAAO,KAAA,IACP,QAAA,GAAW,IAAA,EAAM,KAAA,EAAO,KAAA,UAAe,KAAA,EAAO,KAAA,OAAY,OAAA,GACzD,OAAA;;;;;iBAea,OAAA,CAAA;;;;;;iBASA,iBAAA,CAAkB,GAAA,WAAc,MAAA"}
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -4,7 +4,8 @@ import { ConsoleColors, ConsoleStyles, logCopilotKitPlatformMessage, logStyled,
|
|
|
4
4
|
import { BANNER_ERROR_NAMES, COPILOT_CLOUD_ERROR_NAMES, ConfigurationError, CopilotKitAgentDiscoveryError, CopilotKitApiDiscoveryError, CopilotKitError, CopilotKitErrorCode, CopilotKitLowLevelError, CopilotKitMisuseError, CopilotKitRemoteEndpointDiscoveryError, CopilotKitVersionMismatchError, ERROR_CONFIG, ERROR_NAMES, ErrorVisibility, MissingPublicApiKeyError, ResolvedCopilotKitError, Severity, UpgradeRequiredError, ensureStructuredError, getPossibleVersionMismatch, isStructuredCopilotKitError } from "./errors.mjs";
|
|
5
5
|
import { JSONSchema, JSONSchemaArray, JSONSchemaBoolean, JSONSchemaNumber, JSONSchemaObject, JSONSchemaString, actionParametersToJsonSchema, convertJsonSchemaToZodSchema, getZodParameters, jsonSchemaToActionParameters } from "./json-schema.mjs";
|
|
6
6
|
import { InspectorMetadataV1, parseInspectorMetadataV1 } from "./inspector-metadata.mjs";
|
|
7
|
-
import {
|
|
7
|
+
import { InspectorVisibilityOptions, shouldEnableInspector } from "./inspector-visibility.mjs";
|
|
8
|
+
import { A2UIRuntimeInfo, AgentDescription, IntelligenceRuntimeInfo, MaybePromise, NonEmptyRecord, RUNTIME_MODE_INTELLIGENCE, RUNTIME_MODE_SSE, RuntimeEntitlementResponse, RuntimeInfo, RuntimeLicenseStatus, RuntimeMode, ThreadEndpointRuntimeInfo } from "./types.mjs";
|
|
8
9
|
import { dataToUUID, isValidUUID, randomId, randomUUID } from "./random-id.mjs";
|
|
9
10
|
import { readBody } from "./requests.mjs";
|
|
10
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/utils/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/utils/index.ts"],"mappings":";;;;;;;;;;;;;;AAmBA;;;;iBAAgB,SAAA,CAAU,IAAA,UAAc,QAAA;AAYxC;;;;AAAA,iBAAgB,gBAAA,CAAiB,IAAA;AAsBjC;;;;;;;;;AAaA;AAbA,iBAAgB,yBAAA,CACd,MAAA,UACA,KAAA,YACE,KAAA;;;;;;;iBAUY,MAAA,gBAAA,CACd,KAAA,EAAO,KAAA,IACP,QAAA,GAAW,IAAA,EAAM,KAAA,EAAO,KAAA,UAAe,KAAA,EAAO,KAAA,OAAY,OAAA,GACzD,OAAA;;;;;iBAea,OAAA,CAAA;;;;;;iBASA,iBAAA,CAAkB,GAAA,WAAc,MAAA"}
|
package/dist/utils/index.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { ConsoleColors, ConsoleStyles, logCopilotKitPlatformMessage, logStyled,
|
|
|
4
4
|
import { BANNER_ERROR_NAMES, COPILOT_CLOUD_ERROR_NAMES, ConfigurationError, CopilotKitAgentDiscoveryError, CopilotKitApiDiscoveryError, CopilotKitError, CopilotKitErrorCode, CopilotKitLowLevelError, CopilotKitMisuseError, CopilotKitRemoteEndpointDiscoveryError, CopilotKitVersionMismatchError, ERROR_CONFIG, ERROR_NAMES, ErrorVisibility, MissingPublicApiKeyError, ResolvedCopilotKitError, Severity, UpgradeRequiredError, ensureStructuredError, getPossibleVersionMismatch, isStructuredCopilotKitError } from "./errors.mjs";
|
|
5
5
|
import { actionParametersToJsonSchema, convertJsonSchemaToZodSchema, getZodParameters, jsonSchemaToActionParameters } from "./json-schema.mjs";
|
|
6
6
|
import { parseInspectorMetadataV1 } from "./inspector-metadata.mjs";
|
|
7
|
+
import { shouldEnableInspector } from "./inspector-visibility.mjs";
|
|
7
8
|
import { RUNTIME_MODE_INTELLIGENCE, RUNTIME_MODE_SSE } from "./types.mjs";
|
|
8
9
|
import { dataToUUID, isValidUUID, randomId, randomUUID } from "./random-id.mjs";
|
|
9
10
|
import { readBody } from "./requests.mjs";
|
package/dist/utils/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from \"./clipboard\";\nexport * from \"./conditions\";\nexport * from \"./console-styling\";\nexport * from \"./errors\";\nexport * from \"./json-schema\";\nexport * from \"./inspector-metadata\";\nexport * from \"./types\";\nexport * from \"./random-id\";\nexport * from \"./requests\";\n\nimport * as PartialJSON from \"partial-json\";\n\n/**\n * Safely parses a JSON string into an object\n * @param json The JSON string to parse\n * @param fallback Optional fallback value to return if parsing fails. If not provided or set to \"unset\", returns null\n * @returns The parsed JSON object, or the fallback value (or null) if parsing fails\n */\nexport function parseJson(json: string, fallback: any = \"unset\") {\n try {\n return JSON.parse(json);\n } catch {\n return fallback === \"unset\" ? null : fallback;\n }\n}\n\n/**\n * Parses a partial/incomplete JSON string, returning as much valid data as possible.\n * Falls back to an empty object if parsing fails entirely.\n */\nexport function partialJSONParse(json: string) {\n try {\n const parsed = PartialJSON.parse(json);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n}\n\n/**\n * Returns an exponential backoff function suitable for Phoenix.js\n * `reconnectAfterMs` and `rejoinAfterMs` options.\n *\n * @param baseMs - Initial delay for the first retry attempt.\n * @param maxMs - Upper bound — delays are capped at this value.\n *\n * Phoenix calls the returned function with a 1-based `tries` count.\n * The delay doubles on each attempt: baseMs, 2×baseMs, 4×baseMs, …, maxMs.\n */\nexport function phoenixExponentialBackoff(\n baseMs: number,\n maxMs: number,\n): (tries: number) => number {\n return (tries: number) => Math.min(baseMs * 2 ** (tries - 1), maxMs);\n}\n\n/**\n * Maps an array of items to a new array, skipping items that throw errors during mapping\n * @param items The array to map\n * @param callback The mapping function to apply to each item\n * @returns A new array containing only the successfully mapped items\n */\nexport function tryMap<TItem, TMapped>(\n items: TItem[],\n callback: (item: TItem, index: number, array: TItem[]) => TMapped,\n): TMapped[] {\n return items.reduce<TMapped[]>((acc, item, index, array) => {\n try {\n acc.push(callback(item, index, array));\n } catch (error) {\n console.error(error);\n }\n return acc;\n }, []);\n}\n\n/**\n * Checks if the current environment is macOS\n * @returns {boolean} True if running on macOS, false otherwise\n */\nexport function isMacOS(): boolean {\n return /Mac|iMac|Macintosh/i.test(navigator.userAgent);\n}\n\n/**\n * Safely parses a JSON string into a tool arguments object.\n * Returns the parsed object only if it's a plain object (not an array, null, etc.).\n * Falls back to an empty object for any non-object JSON value or parse failure.\n */\nexport function safeParseToolArgs(raw: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`,\n );\n return {};\n } catch {\n console.warn(\n \"[CopilotKit] Failed to parse tool arguments, falling back to empty object\",\n );\n return {};\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from \"./clipboard\";\nexport * from \"./conditions\";\nexport * from \"./console-styling\";\nexport * from \"./errors\";\nexport * from \"./json-schema\";\nexport * from \"./inspector-metadata\";\nexport * from \"./inspector-visibility\";\nexport * from \"./types\";\nexport * from \"./random-id\";\nexport * from \"./requests\";\n\nimport * as PartialJSON from \"partial-json\";\n\n/**\n * Safely parses a JSON string into an object\n * @param json The JSON string to parse\n * @param fallback Optional fallback value to return if parsing fails. If not provided or set to \"unset\", returns null\n * @returns The parsed JSON object, or the fallback value (or null) if parsing fails\n */\nexport function parseJson(json: string, fallback: any = \"unset\") {\n try {\n return JSON.parse(json);\n } catch {\n return fallback === \"unset\" ? null : fallback;\n }\n}\n\n/**\n * Parses a partial/incomplete JSON string, returning as much valid data as possible.\n * Falls back to an empty object if parsing fails entirely.\n */\nexport function partialJSONParse(json: string) {\n try {\n const parsed = PartialJSON.parse(json);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n return {};\n } catch {\n return {};\n }\n}\n\n/**\n * Returns an exponential backoff function suitable for Phoenix.js\n * `reconnectAfterMs` and `rejoinAfterMs` options.\n *\n * @param baseMs - Initial delay for the first retry attempt.\n * @param maxMs - Upper bound — delays are capped at this value.\n *\n * Phoenix calls the returned function with a 1-based `tries` count.\n * The delay doubles on each attempt: baseMs, 2×baseMs, 4×baseMs, …, maxMs.\n */\nexport function phoenixExponentialBackoff(\n baseMs: number,\n maxMs: number,\n): (tries: number) => number {\n return (tries: number) => Math.min(baseMs * 2 ** (tries - 1), maxMs);\n}\n\n/**\n * Maps an array of items to a new array, skipping items that throw errors during mapping\n * @param items The array to map\n * @param callback The mapping function to apply to each item\n * @returns A new array containing only the successfully mapped items\n */\nexport function tryMap<TItem, TMapped>(\n items: TItem[],\n callback: (item: TItem, index: number, array: TItem[]) => TMapped,\n): TMapped[] {\n return items.reduce<TMapped[]>((acc, item, index, array) => {\n try {\n acc.push(callback(item, index, array));\n } catch (error) {\n console.error(error);\n }\n return acc;\n }, []);\n}\n\n/**\n * Checks if the current environment is macOS\n * @returns {boolean} True if running on macOS, false otherwise\n */\nexport function isMacOS(): boolean {\n return /Mac|iMac|Macintosh/i.test(navigator.userAgent);\n}\n\n/**\n * Safely parses a JSON string into a tool arguments object.\n * Returns the parsed object only if it's a plain object (not an array, null, etc.).\n * Falls back to an empty object for any non-object JSON value or parse failure.\n */\nexport function safeParseToolArgs(raw: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed;\n }\n console.warn(\n `[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`,\n );\n return {};\n } catch {\n console.warn(\n \"[CopilotKit] Failed to parse tool arguments, falling back to empty object\",\n );\n return {};\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,UAAU,MAAc,WAAgB,SAAS;AAC/D,KAAI;AACF,SAAO,KAAK,MAAM,KAAK;SACjB;AACN,SAAO,aAAa,UAAU,OAAO;;;;;;;AAQzC,SAAgB,iBAAiB,MAAc;AAC7C,KAAI;EACF,MAAM,SAAS,YAAY,MAAM,KAAK;AACtC,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAChE,QAAO;AAET,SAAO,EAAE;SACH;AACN,SAAO,EAAE;;;;;;;;;;;;;AAcb,SAAgB,0BACd,QACA,OAC2B;AAC3B,SAAQ,UAAkB,KAAK,IAAI,SAAS,MAAM,QAAQ,IAAI,MAAM;;;;;;;;AAStE,SAAgB,OACd,OACA,UACW;AACX,QAAO,MAAM,QAAmB,KAAK,MAAM,OAAO,UAAU;AAC1D,MAAI;AACF,OAAI,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC;WAC/B,OAAO;AACd,WAAQ,MAAM,MAAM;;AAEtB,SAAO;IACN,EAAE,CAAC;;;;;;AAOR,SAAgB,UAAmB;AACjC,QAAO,sBAAsB,KAAK,UAAU,UAAU;;;;;;;AAQxD,SAAgB,kBAAkB,KAAsC;AACtE,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,OAAO,CAChE,QAAO;AAET,UAAQ,KACN,qDAAqD,OAAO,OAAO,iCACpE;AACD,SAAO,EAAE;SACH;AACN,UAAQ,KACN,4EACD;AACD,SAAO,EAAE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/utils/inspector-visibility.ts
|
|
3
|
+
/**
|
|
4
|
+
* The Inspector is a development-only browser tool. Consumers may disable it,
|
|
5
|
+
* but an explicit `true` never overrides a production or server environment.
|
|
6
|
+
*/
|
|
7
|
+
function shouldEnableInspector({ enableInspector, isBrowser, isDevelopment }) {
|
|
8
|
+
return isBrowser && isDevelopment && enableInspector !== false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.shouldEnableInspector = shouldEnableInspector;
|
|
13
|
+
//# sourceMappingURL=inspector-visibility.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector-visibility.cjs","names":[],"sources":["../../src/utils/inspector-visibility.ts"],"sourcesContent":["export interface InspectorVisibilityOptions {\n enableInspector?: boolean;\n isBrowser: boolean;\n isDevelopment: boolean;\n}\n\n/**\n * The Inspector is a development-only browser tool. Consumers may disable it,\n * but an explicit `true` never overrides a production or server environment.\n */\nexport function shouldEnableInspector({\n enableInspector,\n isBrowser,\n isDevelopment,\n}: InspectorVisibilityOptions): boolean {\n return isBrowser && isDevelopment && enableInspector !== false;\n}\n"],"mappings":";;;;;;AAUA,SAAgB,sBAAsB,EACpC,iBACA,WACA,iBACsC;AACtC,QAAO,aAAa,iBAAiB,oBAAoB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/utils/inspector-visibility.d.ts
|
|
2
|
+
interface InspectorVisibilityOptions {
|
|
3
|
+
enableInspector?: boolean;
|
|
4
|
+
isBrowser: boolean;
|
|
5
|
+
isDevelopment: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The Inspector is a development-only browser tool. Consumers may disable it,
|
|
9
|
+
* but an explicit `true` never overrides a production or server environment.
|
|
10
|
+
*/
|
|
11
|
+
declare function shouldEnableInspector({
|
|
12
|
+
enableInspector,
|
|
13
|
+
isBrowser,
|
|
14
|
+
isDevelopment
|
|
15
|
+
}: InspectorVisibilityOptions): boolean;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { InspectorVisibilityOptions, shouldEnableInspector };
|
|
18
|
+
//# sourceMappingURL=inspector-visibility.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector-visibility.d.cts","names":[],"sources":["../../src/utils/inspector-visibility.ts"],"mappings":";UAAiB,0BAAA;EACf,eAAA;EACA,SAAA;EACA,aAAA;AAAA;;;;;iBAOc,qBAAA,CAAA;EACd,eAAA;EACA,SAAA;EACA;AAAA,GACC,0BAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/utils/inspector-visibility.d.ts
|
|
2
|
+
interface InspectorVisibilityOptions {
|
|
3
|
+
enableInspector?: boolean;
|
|
4
|
+
isBrowser: boolean;
|
|
5
|
+
isDevelopment: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The Inspector is a development-only browser tool. Consumers may disable it,
|
|
9
|
+
* but an explicit `true` never overrides a production or server environment.
|
|
10
|
+
*/
|
|
11
|
+
declare function shouldEnableInspector({
|
|
12
|
+
enableInspector,
|
|
13
|
+
isBrowser,
|
|
14
|
+
isDevelopment
|
|
15
|
+
}: InspectorVisibilityOptions): boolean;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { InspectorVisibilityOptions, shouldEnableInspector };
|
|
18
|
+
//# sourceMappingURL=inspector-visibility.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector-visibility.d.mts","names":[],"sources":["../../src/utils/inspector-visibility.ts"],"mappings":";UAAiB,0BAAA;EACf,eAAA;EACA,SAAA;EACA,aAAA;AAAA;;;;;iBAOc,qBAAA,CAAA;EACd,eAAA;EACA,SAAA;EACA;AAAA,GACC,0BAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/utils/inspector-visibility.ts
|
|
2
|
+
/**
|
|
3
|
+
* The Inspector is a development-only browser tool. Consumers may disable it,
|
|
4
|
+
* but an explicit `true` never overrides a production or server environment.
|
|
5
|
+
*/
|
|
6
|
+
function shouldEnableInspector({ enableInspector, isBrowser, isDevelopment }) {
|
|
7
|
+
return isBrowser && isDevelopment && enableInspector !== false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { shouldEnableInspector };
|
|
12
|
+
//# sourceMappingURL=inspector-visibility.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector-visibility.mjs","names":[],"sources":["../../src/utils/inspector-visibility.ts"],"sourcesContent":["export interface InspectorVisibilityOptions {\n enableInspector?: boolean;\n isBrowser: boolean;\n isDevelopment: boolean;\n}\n\n/**\n * The Inspector is a development-only browser tool. Consumers may disable it,\n * but an explicit `true` never overrides a production or server environment.\n */\nexport function shouldEnableInspector({\n enableInspector,\n isBrowser,\n isDevelopment,\n}: InspectorVisibilityOptions): boolean {\n return isBrowser && isDevelopment && enableInspector !== false;\n}\n"],"mappings":";;;;;AAUA,SAAgB,sBAAsB,EACpC,iBACA,WACA,iBACsC;AACtC,QAAO,aAAa,iBAAiB,oBAAoB"}
|
package/dist/utils/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","names":[],"sources":["../../src/utils/types.ts"],"sourcesContent":["import type { AgentCapabilities } from \"@ag-ui/core\";\n\nexport type MaybePromise<T> = T | PromiseLike<T>;\n\n/**\n * More specific utility for records with at least one key\n */\nexport type NonEmptyRecord<T> =\n T extends Record<string, unknown>\n ? keyof T extends never\n ? never\n : T\n : never;\n\n/**\n * Type representing an agent's basic information\n */\nexport interface AgentDescription {\n name: string;\n className: string;\n description: string;\n capabilities?: AgentCapabilities;\n}\n\nexport type RuntimeMode = \"sse\" | \"intelligence\";\n\nexport const RUNTIME_MODE_SSE = \"sse\" as const;\nexport const RUNTIME_MODE_INTELLIGENCE = \"intelligence\" as const;\n\nexport interface IntelligenceRuntimeInfo {\n wsUrl: string;\n}\n\nexport interface ThreadEndpointRuntimeInfo {\n list: boolean;\n inspect: boolean;\n mutations: boolean;\n realtimeMetadata: boolean;\n}\n\nexport type RuntimeLicenseStatus =\n | \"valid\"\n | \"none\"\n | \"expired\"\n | \"expiring\"\n | \"invalid\"\n | \"unknown\";\n\nexport interface A2UIRuntimeInfo {\n enabled: boolean;\n /**\n * Agent ids the runtime applies A2UI to. When omitted, A2UI applies to\n * every agent served by the runtime.\n */\n agents?: string[];\n}\n\nexport interface RuntimeInfo {\n version: string;\n agents: Record<string, AgentDescription>;\n audioFileTranscriptionEnabled: boolean;\n mode: RuntimeMode;\n intelligence?: IntelligenceRuntimeInfo;\n threadEndpoints?: ThreadEndpointRuntimeInfo;\n /** Whether this runtime exposes trusted inspector metadata. */\n inspectorMetadata?: boolean;\n /**\n * When true, the runtime exposes POST /agent/:agentId/suggest for stateless\n * suggestion generation. Absent on older runtimes; clients fall back to a\n * client-side agent run.\n */\n suggestions?: boolean;\n /**\n * @deprecated Use `a2ui` instead, which preserves per-agent scoping.\n * Kept for backward compatibility with older clients.\n */\n a2uiEnabled?: boolean;\n a2ui?: A2UIRuntimeInfo;\n openGenerativeUIEnabled?: boolean;\n licenseStatus?: RuntimeLicenseStatus;\n telemetryDisabled?: boolean;\n}\n"],"mappings":";;AA0BA,MAAa,mBAAmB;AAChC,MAAa,4BAA4B"}
|
|
1
|
+
{"version":3,"file":"types.cjs","names":[],"sources":["../../src/utils/types.ts"],"sourcesContent":["import type { AgentCapabilities } from \"@ag-ui/core\";\n\nexport type MaybePromise<T> = T | PromiseLike<T>;\n\n/**\n * More specific utility for records with at least one key\n */\nexport type NonEmptyRecord<T> =\n T extends Record<string, unknown>\n ? keyof T extends never\n ? never\n : T\n : never;\n\n/**\n * Type representing an agent's basic information\n */\nexport interface AgentDescription {\n name: string;\n className: string;\n description: string;\n capabilities?: AgentCapabilities;\n}\n\nexport type RuntimeMode = \"sse\" | \"intelligence\";\n\nexport const RUNTIME_MODE_SSE = \"sse\" as const;\nexport const RUNTIME_MODE_INTELLIGENCE = \"intelligence\" as const;\n\nexport interface IntelligenceRuntimeInfo {\n wsUrl: string;\n}\n\nexport interface ThreadEndpointRuntimeInfo {\n list: boolean;\n inspect: boolean;\n mutations: boolean;\n realtimeMetadata: boolean;\n}\n\nexport type RuntimeLicenseStatus =\n | \"valid\"\n | \"none\"\n | \"expired\"\n | \"expiring\"\n | \"invalid\"\n | \"unknown\";\n\n/** Runtime entitlement authority resolved by a managed or self-hosted backend. */\ninterface RuntimeEntitlement {\n /** Whether the resolved entitlement currently grants product access. */\n active: boolean;\n /** Deployment authority that produced this entitlement. */\n source: \"managedOrgSubscription\" | \"selfHostedDeploymentLicense\";\n /** Boolean feature grants keyed by stable feature id. */\n features: Record<string, boolean>;\n /** Numeric limits keyed by stable feature id. */\n limits: Record<string, number>;\n /** Optional catalog plan code supplied by the entitlement authority. */\n planCode?: string;\n /** Optional lower-level source metadata supplied by the authority. */\n entitlementSource?: string;\n}\n\n/** Public diagnostic returned when Runtime entitlement resolution is not ready. */\ninterface RuntimeEntitlementError {\n /** Stable backend or SDK error code. */\n code: string;\n /** Safe human-readable diagnostic. */\n message: string;\n /** Whether a later resolution attempt may succeed without reconfiguration. */\n retryable: boolean;\n /** Optional originating request correlation id. */\n requestId?: string;\n /** Optional originating trace correlation id. */\n traceId?: string;\n}\n\n/** Successfully resolved Runtime entitlement response. */\ninterface RuntimeEntitlementReadyResponse {\n status: \"ready\";\n entitlement: RuntimeEntitlement;\n error?: never;\n}\n\n/** Structured non-ready Runtime entitlement response. */\ninterface RuntimeEntitlementErrorResponse {\n status: \"degraded\" | \"misconfigured\" | \"unavailable\";\n entitlement?: never;\n error: RuntimeEntitlementError;\n}\n\n/** Final structured Runtime entitlement response exposed through `/info`. */\nexport type RuntimeEntitlementResponse =\n | RuntimeEntitlementReadyResponse\n | RuntimeEntitlementErrorResponse;\n\nexport interface A2UIRuntimeInfo {\n enabled: boolean;\n /**\n * Agent ids the runtime applies A2UI to. When omitted, A2UI applies to\n * every agent served by the runtime.\n */\n agents?: string[];\n}\n\nexport interface RuntimeInfo {\n version: string;\n agents: Record<string, AgentDescription>;\n audioFileTranscriptionEnabled: boolean;\n mode: RuntimeMode;\n intelligence?: IntelligenceRuntimeInfo;\n threadEndpoints?: ThreadEndpointRuntimeInfo;\n /** Whether this runtime exposes trusted inspector metadata. */\n inspectorMetadata?: boolean;\n /**\n * When true, the runtime exposes POST /agent/:agentId/suggest for stateless\n * suggestion generation. Absent on older runtimes; clients fall back to a\n * client-side agent run.\n */\n suggestions?: boolean;\n /**\n * @deprecated Use `a2ui` instead, which preserves per-agent scoping.\n * Kept for backward compatibility with older clients.\n */\n a2uiEnabled?: boolean;\n a2ui?: A2UIRuntimeInfo;\n openGenerativeUIEnabled?: boolean;\n /** Structured Runtime-level entitlement authority, when advertised. */\n runtimeEntitlements?: RuntimeEntitlementResponse;\n /** Legacy compatibility diagnostic retained for older Core/Inspector clients. */\n licenseStatus?: RuntimeLicenseStatus;\n telemetryDisabled?: boolean;\n}\n"],"mappings":";;AA0BA,MAAa,mBAAmB;AAChC,MAAa,4BAA4B"}
|