@kortyx/usage-telemetry 0.3.0 → 0.5.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/CHANGELOG.md +17 -0
- package/README.md +126 -4
- package/dist/browser-node.d.ts +11 -3
- package/dist/browser-node.js +549 -23
- package/dist/browser-node.js.map +1 -1
- package/dist/{client-rVwo4XAO.d.ts → client-BPjAx5oh.d.ts} +8 -5
- package/dist/index.d.ts +12 -3
- package/dist/index.js +543 -23
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +10 -4
- package/dist/node.js +562 -24
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.0](https://github.com/kortyx-io/kortyx/compare/usage-telemetry-v0.4.0...usage-telemetry-v0.5.0) (2026-10-18)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **cli:** validate topology and update compatible dependencies ([6c16ef3](https://github.com/kortyx-io/kortyx/commit/6c16ef3d1c9e8329d31f1a28e87aa26ae6dbe651))
|
|
9
|
+
* **studio:** add contextual help and organize product documentation ([#366](https://github.com/kortyx-io/kortyx/issues/366)) ([aa4a624](https://github.com/kortyx-io/kortyx/commit/aa4a6242f6294e0f96968a8021440cdc55467121))
|
|
10
|
+
* **studio:** add sample project and guided onboarding ([#363](https://github.com/kortyx-io/kortyx/issues/363)) ([25da0b9](https://github.com/kortyx-io/kortyx/commit/25da0b9c92072446a7503b23ba4f157aebec8185))
|
|
11
|
+
|
|
12
|
+
## [0.4.0](https://github.com/kortyx-io/kortyx/compare/usage-telemetry-v0.3.0...usage-telemetry-v0.4.0) (2026-10-16)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **studio:** standardize tables, filters and column behavior ([#353](https://github.com/kortyx-io/kortyx/issues/353)) ([c662e59](https://github.com/kortyx-io/kortyx/commit/c662e59d814a6a9f12c709595968ee7b1ece3191))
|
|
18
|
+
* **telemetry:** improve failure classification and add CLI usage ([#355](https://github.com/kortyx-io/kortyx/issues/355)) ([c5fbbed](https://github.com/kortyx-io/kortyx/commit/c5fbbed3064ea7b2b3020617db7ce09d1b175db3))
|
|
19
|
+
|
|
3
20
|
## [0.3.0](https://github.com/kortyx-io/kortyx/compare/usage-telemetry-v0.2.0...usage-telemetry-v0.3.0) (2026-10-13)
|
|
4
21
|
|
|
5
22
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Kortyx usage telemetry
|
|
2
2
|
|
|
3
|
-
Maintainer usage telemetry measures adoption and reliability of the SDK and OSS Studio. It is separate from customer observability in `@kortyx/telemetry` and `@kortyx/otel`. The default destination is Kortyx's EU PostHog Production project, using its public capture key. Consumers need no personal API token.
|
|
3
|
+
Maintainer usage telemetry measures adoption and reliability of the SDK, CLI and OSS Studio. It is separate from customer observability in `@kortyx/telemetry` and `@kortyx/otel`. The default destination is Kortyx's EU PostHog Production project, using its public capture key. Consumers need no personal API token.
|
|
4
4
|
|
|
5
5
|
## Controls
|
|
6
6
|
|
|
@@ -14,6 +14,7 @@ Set these in the SDK process or Studio deployment environment. CLI-generated Com
|
|
|
14
14
|
| `KORTYX_USAGE_TELEMETRY_POSTHOG_HOST` | Overrides the ingestion host; defaults to `https://eu.i.posthog.com` |
|
|
15
15
|
| `KORTYX_USAGE_TELEMETRY_ENDPOINT` | Replaces PostHog with a collector accepting `{ identity, records }` |
|
|
16
16
|
| `KORTYX_USAGE_TELEMETRY_ENVIRONMENT=staging` | Labels maintainer staging; pair it with that project's capture key |
|
|
17
|
+
| `KORTYX_USAGE_TELEMETRY_TRAFFIC_SOURCE` | Explicit `internal`, `synthetic` or `external` cohort; otherwise `unknown`. CI does not imply synthetic traffic |
|
|
17
18
|
| `KORTYX_USAGE_TELEMETRY_ID` | Optional random UUID for deliberate identity sharing between Node processes |
|
|
18
19
|
|
|
19
20
|
Tests (`NODE_ENV=test`) disable the default Node integration. Consumer `NODE_ENV` and `CI` supply a coarse runtime mode; they do not select the maintainer project. Browser bootstrap receives only public configuration from Studio's server environment, so no `NEXT_PUBLIC_` variables are needed. Debug output contains approved dimensions and aggregate counts, never application payloads.
|
|
@@ -24,13 +25,28 @@ Node delivery lazily stores a random installation UUID in `~/.config/kortyx/usag
|
|
|
24
25
|
|
|
25
26
|
The shared catalog allows fixed operation names, outcome enums, Kortyx release versions, provider families, storage/transport kinds, coarse HTTP status, known error codes and booleans. Arbitrary property keys are dropped; unrecognized enum values and error codes become `other`. The error projection reads only own data properties and does not invoke application getters.
|
|
26
27
|
|
|
28
|
+
Sample chapters use the bounded `studio.sample` chapter/step catalog, including
|
|
29
|
+
optional `error-diagnostics` and `evaluation-progress`. Optional starts/completions
|
|
30
|
+
have their own chapter denominator and do not increase the six-chapter full-tour
|
|
31
|
+
denominator. Completion is a displayed-guide outcome, not proof of learning.
|
|
32
|
+
|
|
33
|
+
Studio page explanations use `studio.help` with finite `help_page`, `help_step`,
|
|
34
|
+
`help_context` (real/sample), and `help_action` values. Starts count explanation
|
|
35
|
+
attempts; step events count displayed steps, including Back. Completion, skip,
|
|
36
|
+
exit, error, and example request/accept/cancel distinguish local help from a
|
|
37
|
+
confirmed sample transfer. Compare completions against starts within the same
|
|
38
|
+
page/context cohort, accounting for best-effort delivery and abandoned tabs.
|
|
39
|
+
Record identifiers, URLs, selectors, setting values, and page content are excluded.
|
|
40
|
+
Page-help facts are allowed in sample views while ordinary execution metrics remain
|
|
41
|
+
suppressed; they do not measure SDK activation or customer execution outcomes.
|
|
42
|
+
|
|
27
43
|
Prompts, inputs/outputs, messages, schemas, workflow/node/tool names, URLs, paths, custom application error codes, customer IDs, credentials, raw errors and stacks are excluded. Capture requests omit browser cookies and referrers, disable PostHog person profiles and geolocation enrichment, and send `$ip: null`. Network infrastructure still receives a request's source IP; the payload is not proof of legal anonymity. There is no autocapture, session replay or global exception handler.
|
|
28
44
|
|
|
29
45
|
Records aggregate matching operations, outcomes and approved dimensions over a 60-second flush window. A scope finishes once. Successes and failures use the same counting policy. `usage.operation` records reliability and duration; `usage.feature` records deliberate adoption or explicit feature configuration. Background reads/refreshes have separate origins and must not be used as click counts.
|
|
30
46
|
|
|
31
47
|
Each component client buffers at most 64 distinct groups and sends at most 120 groups per hour. A group can represent many attempts through `count`. Duration buckets are noncumulative: ≤10ms, (10,100], (100,1,000], (1,000,10,000], (10,000,60,000], >60,000ms. Query `duration_total_ms / count` for means or combine bucket counts for approximate distributions. Restrict latency queries to `usage.operation`.
|
|
32
48
|
|
|
33
|
-
Delivery is best effort, single-flight, with a two-second transport timeout, no retries and unreferenced Node timers. SDK operations never await analytics delivery or change results because collection fails. The
|
|
49
|
+
Delivery is best effort, single-flight, with a two-second transport timeout, no retries and unreferenced Node timers. SDK operations never await analytics delivery or change results because collection fails. The CLI flushes registered component clients after command parsing/execution, waiting at most two seconds even for a custom transport. Setup stages and command invocations are separate measurements. Browser visibility changes request a flush. Offline, disabled, terminated or short-lived processes can lose records; call the helper's `flush()` explicitly at an application-controlled shutdown boundary when appropriate. No disk event queue or crash detection is implied. `stats()` exposes local pending/dropped/delivered group counts. Budgets are per component and process, not an organization-wide spending guarantee; PostHog's $0 billing limits remain the financial control.
|
|
34
50
|
|
|
35
51
|
## Reusable boundaries
|
|
36
52
|
|
|
@@ -78,14 +94,120 @@ aggregation and failure-independent delivery apply unchanged.
|
|
|
78
94
|
|
|
79
95
|
SDK boundaries include initialization, registry resolution, direct execution/resume, chat admission, terminal graph execution, response completion, model and tool execution, structured output, explicit response completion, prompt resolution, eval outcomes, MCP connection/discovery/close, checkpoint operations and observability export attempts. Early response completion and later graph failure are separate outcomes. An eval quality failure is distinct from an execution error.
|
|
80
96
|
|
|
81
|
-
Studio boundaries include CLI setup, API requests/ingest, server reads and parse failures, first-use guidance and observed data, navigation, tab/trace inspection, render failures/retries, prompt actions, eval launch/read/cancel and live refresh/reconnect. Prompt and eval browser actions measure request acceptance;
|
|
97
|
+
Studio boundaries include CLI setup, API requests/ingest, server reads and parse failures, first-use guidance and observed data, navigation, tab/trace inspection, render failures/retries, prompt actions, eval launch/read/cancel and live refresh/reconnect. Prompt and eval browser actions measure request acceptance. The built-in eval worker separately measures persisted terminal results; its attempt and legacy run units are described below. SDK eval configuration rejection is included with phase `configuration`.
|
|
82
98
|
|
|
83
|
-
The [opportunity inventory](../../docs/audits/sdk-studio-usage-telemetry.md) covers remaining node/parallel/child execution, prompt cache/refresh, persistence internals, exporter queue loss, deeper filters/saved views, worker
|
|
99
|
+
The [opportunity inventory](../../docs/audits/sdk-studio-usage-telemetry.md) covers remaining node/parallel/child execution, prompt cache/refresh, persistence internals, exporter queue loss, deeper filters/saved views, deeper worker phases, reviews and upgrade phases. Reserved catalog operations are not evidence that these boundaries already emit. Feature-flag evaluation and exposure are a future addition.
|
|
84
100
|
|
|
85
101
|
Use `sum(properties.count)`, rather than raw PostHog event count, to measure attempts. For a comparable component/operation cohort, failure rate is `sum(count where outcome = failed) / sum(count for completed operation outcomes)`. Decide explicitly whether cancellations, denial and suspension belong in the denominator. Compare installation reach, repeated use and failure rate by release; do not rank features solely by workload volume. PostHog funnels over aggregates give coarse observed ordering (flush windows can obscure exact ordering), not exact user-session sequences or time since npm installation.
|
|
86
102
|
|
|
103
|
+
## Measurement quality (version 2)
|
|
104
|
+
|
|
105
|
+
The envelope remains `schema_version: 1`; additive approved properties carry
|
|
106
|
+
`measurement_version: "2"`. Historical events without it retain their old coverage.
|
|
107
|
+
Compare matching measurement versions, release, component, operation, origin,
|
|
108
|
+
action, analytics environment and runtime mode. Never add up all SDK operations
|
|
109
|
+
as workflow executions.
|
|
110
|
+
|
|
111
|
+
| Unit (`measurement_kind`) | Counting boundary |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `invocation` | One CLI command parse/action outcome or SDK eval `run()` call, including rejected configuration |
|
|
114
|
+
| `execution` | SDK terminal graph execution; persisted legacy worker suite run |
|
|
115
|
+
| `attempt` | Each model/export send attempt; each claimed eval worker case/repetition attempt |
|
|
116
|
+
| `chunk`, `output`, `update` | Structured text deltas, final output, other updates; workload volume, not feature adoption |
|
|
117
|
+
| `stage` | A Studio setup phase, separate from CLI command completion |
|
|
118
|
+
| `poll` | Background Studio reads, including diagnostic prefetch; not deliberate inspection |
|
|
119
|
+
| `request`, `call` | Studio request or other SDK API call outcome |
|
|
120
|
+
| `feature`, `observation` | Deliberate/configured use versus server/background observation |
|
|
121
|
+
|
|
122
|
+
`runtime_mode` uses Node `CI` / `NODE_ENV`, independently of the destination
|
|
123
|
+
project. Node factories and Studio browser bootstrap carry the same safe context.
|
|
124
|
+
`traffic_source` is explicit: `unknown` is not evidence of external customer use.
|
|
125
|
+
Pseudonymous installation/browser/process reach is not a count of customers.
|
|
126
|
+
|
|
127
|
+
Failures always have an approved `error_code` and `error_category`. Unclassified
|
|
128
|
+
explicit failures use `UNCLASSIFIED_FAILURE`; inspected unknown errors use `other`.
|
|
129
|
+
The classifier reads at most eight objects, three links deep, following own data
|
|
130
|
+
fields `failure`, `cause`, and `error`. Known network codes, HTTP classes, framework
|
|
131
|
+
failure descriptors and optional bounded `cause_code`/`cause_category`/`retryable`
|
|
132
|
+
help distinguish provider, transport, validation and configuration problems. Eval
|
|
133
|
+
failures also project the first issue's approved `eval_phase`; multiple issues in
|
|
134
|
+
one run are not a complete failure census.
|
|
135
|
+
Messages, stacks, diagnostic IDs and exception serialization remain excluded.
|
|
136
|
+
Cancellation, suspension, limits, eval quality failures and ungraded outcomes stay
|
|
137
|
+
separate from technical failures. A known category is not proof of a product bug.
|
|
138
|
+
|
|
139
|
+
Exporter records add bucketed `batch_size`, `retry_attempt`, `retried` and
|
|
140
|
+
`recovered`. Recovery means a successful send after a retry, not a correlated
|
|
141
|
+
end-to-end delivery guarantee. Recursive split sends are separate attempts.
|
|
142
|
+
|
|
143
|
+
Each successful normal delivery may carry `usage_dropped_observations` and
|
|
144
|
+
`usage_failed_batches` once, as deltas since the last delivered health snapshot.
|
|
145
|
+
They include cardinality/budget losses and identity/transport failures; local
|
|
146
|
+
`stats().dropped` still counts groups. Health never bypasses budgets, creates its
|
|
147
|
+
own event, or persists on disk. Permanently offline, crashed, disabled or restarted
|
|
148
|
+
processes cannot report their lost tail. These counters expose observed loss;
|
|
149
|
+
they cannot reconstruct unbiased feature shares after selective group dropping.
|
|
150
|
+
A failed or ambiguous delivery may have reached ingestion: these counters describe
|
|
151
|
+
client-observed loss, not verified server loss.
|
|
152
|
+
|
|
153
|
+
## Eval and diagnostic boundaries
|
|
154
|
+
|
|
155
|
+
Eval launch/settings requests record only booleans for explicit settings and
|
|
156
|
+
case/run deadline overrides. The SDK `sdk.eval` boundary reports configuration
|
|
157
|
+
rejections and safe execution failure codes. Neither timeout values nor judge,
|
|
158
|
+
suite, case, input, criteria or output identities are usage dimensions.
|
|
159
|
+
|
|
160
|
+
The built-in worker emits `studio.eval.execution` only **after** `store.finish`
|
|
161
|
+
persists a result. A claimed case/repetition uses `attempt`; a legacy suite run
|
|
162
|
+
uses `execution`. Cancellation, technical failure, quality failure, ungraded and
|
|
163
|
+
success are separate. Lease loss, process shutdown and a failed persistence write
|
|
164
|
+
do not imply completion. Retries/reclaims may execute again; no global deduplication
|
|
165
|
+
or evaluation-level completion funnel is promised.
|
|
166
|
+
|
|
167
|
+
A custom `EvalJobStore` keeps instrumentation ownership by default. Embedders may
|
|
168
|
+
supply `EvalWorkerOptions.usage` to opt in, or `false` to disable worker emission.
|
|
169
|
+
Choose one owner: either the existing store wrapper or this injected helper.
|
|
170
|
+
Use the same replacement catalog in its helper. Existing custom store adapters do
|
|
171
|
+
not acquire a second public emitter when upgraded. The dispatcher also accepts
|
|
172
|
+
`usage` / `false`; the worker forwards the chosen client or disables dispatch
|
|
173
|
+
collection for a custom store. Retry observations use `origin=server` and are
|
|
174
|
+
separate from terminal results. Standalone dispatcher defaults use component
|
|
175
|
+
`eval_dispatch`, correcting the formerly invalid component spelling.
|
|
176
|
+
|
|
177
|
+
Studio emits a `studio.diagnostic` feature on deliberate error-detail inspection,
|
|
178
|
+
and separately records background diagnostic reads and their failures. Shared table controls emit bounded
|
|
179
|
+
`studio.table.layout` interaction actions, including resize initiation, without
|
|
180
|
+
column names, sizes or saved layout content. Neither
|
|
181
|
+
path sends the displayed error content. Customer-authenticated diagnostic storage
|
|
182
|
+
continues to serve original errors independently.
|
|
183
|
+
|
|
87
184
|
## Proposal: replace direct capture with a Kortyx collector
|
|
88
185
|
|
|
89
186
|
Keep direct EU capture for this slice. A later collector can accept the existing versioned record envelope, validate the catalog again, cap body/group/count sizes, rate-limit installations and total daily ingestion, deduplicate `event_id`, strip network metadata, and route approved releases to the intended PostHog project. Keep retention and operational logs bounded and avoid logging request bodies. Forward asynchronously with its own retry/deduplication policy.
|
|
90
187
|
|
|
91
188
|
This moves abuse controls and global budgets to an owned boundary: a public PostHog capture key can be copied and spoofed, so client caps alone cannot protect ingestion or establish authenticity. Replace the transport or set `KORTYX_USAGE_TELEMETRY_ENDPOINT`; product instrumentation does not change. Endpoint deployment, global limits and project routing belong to that follow-up. Existing released SDK versions continue direct capture until upgraded, so migration must account for them.
|
|
189
|
+
|
|
190
|
+
### Studio contextual help
|
|
191
|
+
|
|
192
|
+
`studio.help` counts feature interactions using `help_action: open | documentation`
|
|
193
|
+
and `help_placement: card | button`. Count closed-to-open card transitions once;
|
|
194
|
+
count documentation navigation intent separately. Compare summed card-footer
|
|
195
|
+
navigation counts with summed card-open counts to assess help use. Standalone
|
|
196
|
+
button clicks are a separate population, and these aggregates do not establish
|
|
197
|
+
unique users, successful page loads, or completed reading. Existing opt-out,
|
|
198
|
+
budgets, aggregation and best-effort delivery apply. No help labels, descriptions,
|
|
199
|
+
URLs, customer identifiers or execution content are collected. This measures
|
|
200
|
+
maintainer product usage separately from customer execution observability.
|
|
201
|
+
|
|
202
|
+
## Topology publication measurement
|
|
203
|
+
|
|
204
|
+
`cli.command` counts each `topology.push` invocation once, including dry runs.
|
|
205
|
+
The allowlisted `topology_strict` boolean records whether optional strict discovery
|
|
206
|
+
was selected. A blocked publication reports `KTX_TOPOLOGY_INCOMPLETE`, validation
|
|
207
|
+
category and `retryable: false`; the CLI's existing terminal outcome and opt-out,
|
|
208
|
+
bounded delivery and exporter-failure behavior apply. Compare `sum(count)` for
|
|
209
|
+
strict invocations with all topology-push invocations to measure adoption, and
|
|
210
|
+
blocked strict invocations with all strict invocations to measure rejection rate.
|
|
211
|
+
Do not interpret a successful invocation as complete discovery when strict mode
|
|
212
|
+
is off or intentional dynamic calls are exempt. Paths, expressions, import traces,
|
|
213
|
+
credentials and diagnostic messages are never usage properties.
|
package/dist/browser-node.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import { U as UsageTelemetry, a as UsageOptions } from './client-
|
|
2
|
-
export { c as createUsageTelemetry, s as scale } from './client-
|
|
1
|
+
import { U as UsageTelemetry, a as UsageOptions } from './client-BPjAx5oh.js';
|
|
2
|
+
export { c as createUsageTelemetry, s as scale } from './client-BPjAx5oh.js';
|
|
3
3
|
|
|
4
|
+
/** Flush registered component replacements without adding another emitter. */
|
|
5
|
+
declare function flushUsageTelemetry(): Promise<void>;
|
|
4
6
|
declare function createNodeUsageTelemetry(options: Pick<UsageOptions, "context"> & Partial<Omit<UsageOptions, "context">>): UsageTelemetry;
|
|
5
7
|
declare function configureUsageTelemetry(component: string, client: UsageTelemetry): void;
|
|
6
8
|
declare function getUsageTelemetry(component: string, version?: string, product?: string): UsageTelemetry;
|
|
7
9
|
declare function usageDisabled(): boolean;
|
|
10
|
+
declare function runtimeUsageContext(): {
|
|
11
|
+
runtimeMode: "unknown";
|
|
12
|
+
trafficSource: "unknown";
|
|
13
|
+
};
|
|
8
14
|
declare function publicUsageConfiguration(): {
|
|
9
15
|
enabled: boolean;
|
|
16
|
+
runtimeMode: "unknown";
|
|
17
|
+
trafficSource: "unknown";
|
|
10
18
|
debug: boolean;
|
|
11
19
|
environment: "production";
|
|
12
20
|
key: string;
|
|
13
21
|
host: string;
|
|
14
22
|
};
|
|
15
23
|
|
|
16
|
-
export { UsageTelemetry, configureUsageTelemetry, createNodeUsageTelemetry, getUsageTelemetry, publicUsageConfiguration, usageDisabled };
|
|
24
|
+
export { UsageTelemetry, configureUsageTelemetry, createNodeUsageTelemetry, flushUsageTelemetry, getUsageTelemetry, publicUsageConfiguration, runtimeUsageContext, usageDisabled };
|