@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/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
classifyUsageError: () => classifyUsageError,
|
|
24
|
+
classifyUsageHttpStatus: () => classifyUsageHttpStatus,
|
|
24
25
|
createCollectorTransport: () => createCollectorTransport,
|
|
25
26
|
createPostHogTransport: () => createPostHogTransport,
|
|
26
27
|
createUsageTelemetry: () => createUsageTelemetry,
|
|
@@ -58,6 +59,8 @@ var operations = [
|
|
|
58
59
|
"sdk.checkpoint.rollback",
|
|
59
60
|
"sdk.export",
|
|
60
61
|
"studio.setup",
|
|
62
|
+
"studio.sample",
|
|
63
|
+
"studio.help",
|
|
61
64
|
"studio.connection",
|
|
62
65
|
"studio.read",
|
|
63
66
|
"studio.render",
|
|
@@ -72,6 +75,11 @@ var operations = [
|
|
|
72
75
|
"studio.settings",
|
|
73
76
|
"studio.update",
|
|
74
77
|
"studio.ingest",
|
|
78
|
+
"cli.command",
|
|
79
|
+
"studio.eval.execution",
|
|
80
|
+
"studio.diagnostic",
|
|
81
|
+
"studio.table.layout",
|
|
82
|
+
"studio.help",
|
|
75
83
|
"cli.topology",
|
|
76
84
|
"cli.eval"
|
|
77
85
|
];
|
|
@@ -86,9 +94,256 @@ var outcomes = [
|
|
|
86
94
|
"ungraded"
|
|
87
95
|
];
|
|
88
96
|
var publicCatalog = {
|
|
89
|
-
products: ["sdk", "oss_studio"],
|
|
97
|
+
products: ["sdk", "oss_studio", "cli"],
|
|
90
98
|
operations,
|
|
91
99
|
properties: {
|
|
100
|
+
help_action: [
|
|
101
|
+
"open",
|
|
102
|
+
"documentation",
|
|
103
|
+
"start",
|
|
104
|
+
"step",
|
|
105
|
+
"complete",
|
|
106
|
+
"skip",
|
|
107
|
+
"exit",
|
|
108
|
+
"error",
|
|
109
|
+
"example_request",
|
|
110
|
+
"example_accept",
|
|
111
|
+
"example_cancel"
|
|
112
|
+
],
|
|
113
|
+
help_page: [
|
|
114
|
+
"runs",
|
|
115
|
+
"run",
|
|
116
|
+
"sessions",
|
|
117
|
+
"session",
|
|
118
|
+
"workflows",
|
|
119
|
+
"interrupts",
|
|
120
|
+
"interrupt",
|
|
121
|
+
"prompts",
|
|
122
|
+
"prompt",
|
|
123
|
+
"prompt-groups",
|
|
124
|
+
"prompt-group",
|
|
125
|
+
"evals",
|
|
126
|
+
"eval-suites",
|
|
127
|
+
"eval-suite",
|
|
128
|
+
"evaluation",
|
|
129
|
+
"eval-run",
|
|
130
|
+
"eval-case",
|
|
131
|
+
"eval-comparison",
|
|
132
|
+
"eval-case-comparison",
|
|
133
|
+
"diagnostic",
|
|
134
|
+
"settings",
|
|
135
|
+
"onboarding",
|
|
136
|
+
"other"
|
|
137
|
+
],
|
|
138
|
+
help_context: ["sample", "real"],
|
|
139
|
+
help_step: [
|
|
140
|
+
"overview",
|
|
141
|
+
"controls",
|
|
142
|
+
"records",
|
|
143
|
+
"tabs",
|
|
144
|
+
"content",
|
|
145
|
+
"navigation",
|
|
146
|
+
"state"
|
|
147
|
+
],
|
|
148
|
+
sample_action: [
|
|
149
|
+
"select",
|
|
150
|
+
"view",
|
|
151
|
+
"hide",
|
|
152
|
+
"show",
|
|
153
|
+
"tour_start",
|
|
154
|
+
"tour_complete",
|
|
155
|
+
"tour_skip",
|
|
156
|
+
"tour_error",
|
|
157
|
+
"tour_step",
|
|
158
|
+
"tour_hub",
|
|
159
|
+
"tour_resume",
|
|
160
|
+
"tour_exit",
|
|
161
|
+
"tour_full_start",
|
|
162
|
+
"tour_full_complete",
|
|
163
|
+
"tour_full_partial",
|
|
164
|
+
"tour_reset"
|
|
165
|
+
],
|
|
166
|
+
tour_chapter: [
|
|
167
|
+
"sample-execution",
|
|
168
|
+
"debug-execution",
|
|
169
|
+
"conversation",
|
|
170
|
+
"approvals",
|
|
171
|
+
"prompt-versions",
|
|
172
|
+
"evaluation-results",
|
|
173
|
+
"error-diagnostics",
|
|
174
|
+
"evaluation-progress",
|
|
175
|
+
"personalize"
|
|
176
|
+
],
|
|
177
|
+
tour_step: [
|
|
178
|
+
"project-selector",
|
|
179
|
+
"sample-run",
|
|
180
|
+
"execution-details",
|
|
181
|
+
"find-failed-run",
|
|
182
|
+
"failure-summary",
|
|
183
|
+
"failure-trace",
|
|
184
|
+
"failure-model-io",
|
|
185
|
+
"session-history",
|
|
186
|
+
"session-runs",
|
|
187
|
+
"workflow-topology",
|
|
188
|
+
"workflow-system",
|
|
189
|
+
"approval-decision",
|
|
190
|
+
"approval-timeline",
|
|
191
|
+
"approval-result",
|
|
192
|
+
"prompt-original",
|
|
193
|
+
"prompt-updated",
|
|
194
|
+
"prompt-diff",
|
|
195
|
+
"suite-definition",
|
|
196
|
+
"evaluation-summary",
|
|
197
|
+
"case-evidence",
|
|
198
|
+
"saved-comparison",
|
|
199
|
+
"diagnostic-exception",
|
|
200
|
+
"diagnostic-capture",
|
|
201
|
+
"diagnostic-context",
|
|
202
|
+
"evaluation-progress-summary",
|
|
203
|
+
"evaluation-grading",
|
|
204
|
+
"evaluation-pending-evidence",
|
|
205
|
+
"appearance",
|
|
206
|
+
"sample-visibility"
|
|
207
|
+
],
|
|
208
|
+
tour_failure: ["load", "target", "entry"],
|
|
209
|
+
tour_mode: ["chapter", "full"],
|
|
210
|
+
tour_version: ["1"],
|
|
211
|
+
help_placement: ["card", "button"],
|
|
212
|
+
measurement_version: ["2"],
|
|
213
|
+
measurement_kind: [
|
|
214
|
+
"invocation",
|
|
215
|
+
"stage",
|
|
216
|
+
"execution",
|
|
217
|
+
"attempt",
|
|
218
|
+
"chunk",
|
|
219
|
+
"output",
|
|
220
|
+
"update",
|
|
221
|
+
"poll",
|
|
222
|
+
"request",
|
|
223
|
+
"call",
|
|
224
|
+
"feature",
|
|
225
|
+
"observation"
|
|
226
|
+
],
|
|
227
|
+
traffic_source: ["internal", "synthetic", "external", "unknown"],
|
|
228
|
+
layout_action: [
|
|
229
|
+
"visibility",
|
|
230
|
+
"show_all",
|
|
231
|
+
"reset",
|
|
232
|
+
"apply",
|
|
233
|
+
"reset_width",
|
|
234
|
+
"pin",
|
|
235
|
+
"unpin",
|
|
236
|
+
"resize",
|
|
237
|
+
"reorder"
|
|
238
|
+
],
|
|
239
|
+
eval_phase: [
|
|
240
|
+
"params",
|
|
241
|
+
"setup",
|
|
242
|
+
"execute",
|
|
243
|
+
"responder",
|
|
244
|
+
"reference",
|
|
245
|
+
"grading",
|
|
246
|
+
"verification",
|
|
247
|
+
"cleanup",
|
|
248
|
+
"reporting"
|
|
249
|
+
],
|
|
250
|
+
cli_resource: ["evals.runs", "evals.suites"],
|
|
251
|
+
retryable: "boolean",
|
|
252
|
+
retried: "boolean",
|
|
253
|
+
recovered: "boolean",
|
|
254
|
+
retry_attempt: ["1", "2-5", "6-20", "21-100", "101+"],
|
|
255
|
+
batch_size: ["1", "2-5", "6-20", "21-100", "101+"],
|
|
256
|
+
http_status_class: ["1xx", "2xx", "3xx", "4xx", "5xx"],
|
|
257
|
+
cause_category: [
|
|
258
|
+
"configuration",
|
|
259
|
+
"provider",
|
|
260
|
+
"validation",
|
|
261
|
+
"domain",
|
|
262
|
+
"workflow",
|
|
263
|
+
"persistence",
|
|
264
|
+
"request",
|
|
265
|
+
"transport",
|
|
266
|
+
"internal",
|
|
267
|
+
"unknown"
|
|
268
|
+
],
|
|
269
|
+
cli_command: [
|
|
270
|
+
"studio.start",
|
|
271
|
+
"studio.stop",
|
|
272
|
+
"studio.restart",
|
|
273
|
+
"studio.status",
|
|
274
|
+
"studio.logs",
|
|
275
|
+
"studio.credentials",
|
|
276
|
+
"studio.reset",
|
|
277
|
+
"studio.prompts",
|
|
278
|
+
"studio.evals",
|
|
279
|
+
"studio.runs",
|
|
280
|
+
"studio.sessions",
|
|
281
|
+
"studio.interrupts",
|
|
282
|
+
"studio.workflows",
|
|
283
|
+
"studio.diagnostics",
|
|
284
|
+
"studio.inspect",
|
|
285
|
+
"studio.doctor",
|
|
286
|
+
"studio.catalogs",
|
|
287
|
+
"connections",
|
|
288
|
+
"evals.run",
|
|
289
|
+
"evals.list",
|
|
290
|
+
"topology.push",
|
|
291
|
+
"help",
|
|
292
|
+
"unknown"
|
|
293
|
+
],
|
|
294
|
+
cli_action: [
|
|
295
|
+
"start",
|
|
296
|
+
"stop",
|
|
297
|
+
"restart",
|
|
298
|
+
"status",
|
|
299
|
+
"logs",
|
|
300
|
+
"credentials",
|
|
301
|
+
"reset",
|
|
302
|
+
"run",
|
|
303
|
+
"list",
|
|
304
|
+
"get",
|
|
305
|
+
"show",
|
|
306
|
+
"inspect",
|
|
307
|
+
"analyze",
|
|
308
|
+
"download",
|
|
309
|
+
"doctor",
|
|
310
|
+
"cancel",
|
|
311
|
+
"compare",
|
|
312
|
+
"create",
|
|
313
|
+
"update",
|
|
314
|
+
"delete",
|
|
315
|
+
"import",
|
|
316
|
+
"export",
|
|
317
|
+
"pull",
|
|
318
|
+
"push",
|
|
319
|
+
"add",
|
|
320
|
+
"remove",
|
|
321
|
+
"use",
|
|
322
|
+
"verify",
|
|
323
|
+
"versions",
|
|
324
|
+
"diff",
|
|
325
|
+
"validate",
|
|
326
|
+
"action",
|
|
327
|
+
"tag",
|
|
328
|
+
"untag",
|
|
329
|
+
"rollback",
|
|
330
|
+
"promote",
|
|
331
|
+
"archive",
|
|
332
|
+
"restore",
|
|
333
|
+
"test",
|
|
334
|
+
"copy",
|
|
335
|
+
"apply",
|
|
336
|
+
"wait",
|
|
337
|
+
"catalogs",
|
|
338
|
+
"help",
|
|
339
|
+
"unknown"
|
|
340
|
+
],
|
|
341
|
+
dry_run: "boolean",
|
|
342
|
+
json_output: "boolean",
|
|
343
|
+
topology_strict: "boolean",
|
|
344
|
+
settings_override: "boolean",
|
|
345
|
+
case_timeout_override: "boolean",
|
|
346
|
+
run_timeout_override: "boolean",
|
|
92
347
|
phase: [
|
|
93
348
|
"admission",
|
|
94
349
|
"execution",
|
|
@@ -233,6 +488,7 @@ var publicCatalog = {
|
|
|
233
488
|
"pending",
|
|
234
489
|
"expired"
|
|
235
490
|
],
|
|
491
|
+
match: ["all", "any"],
|
|
236
492
|
filter: [
|
|
237
493
|
"search",
|
|
238
494
|
"status",
|
|
@@ -265,6 +521,7 @@ var publicCatalog = {
|
|
|
265
521
|
"401",
|
|
266
522
|
"403",
|
|
267
523
|
"404",
|
|
524
|
+
"408",
|
|
268
525
|
"409",
|
|
269
526
|
"413",
|
|
270
527
|
"422",
|
|
@@ -288,6 +545,48 @@ var publicCatalog = {
|
|
|
288
545
|
},
|
|
289
546
|
// Built-in contracts only; application codes and provider response text are excluded.
|
|
290
547
|
errorCodes: [
|
|
548
|
+
"UNCLASSIFIED_FAILURE",
|
|
549
|
+
"HTTP_UNAUTHORIZED",
|
|
550
|
+
"HTTP_FORBIDDEN",
|
|
551
|
+
"HTTP_NOT_FOUND",
|
|
552
|
+
"HTTP_TIMEOUT",
|
|
553
|
+
"HTTP_CONFLICT",
|
|
554
|
+
"HTTP_TOO_LARGE",
|
|
555
|
+
"HTTP_RATE_LIMITED",
|
|
556
|
+
"HTTP_SERVER_ERROR",
|
|
557
|
+
"HTTP_INVALID_REQUEST",
|
|
558
|
+
"NETWORK_DNS_FAILED",
|
|
559
|
+
"NETWORK_CONNECTION_REFUSED",
|
|
560
|
+
"NETWORK_CONNECTION_RESET",
|
|
561
|
+
"NETWORK_TIMEOUT",
|
|
562
|
+
"NETWORK_TLS_FAILED",
|
|
563
|
+
"CLI_ARGUMENT_INVALID",
|
|
564
|
+
"CLI_EXIT_FAILED",
|
|
565
|
+
"KTX_TOPOLOGY_INCOMPLETE",
|
|
566
|
+
"STUDIO_NOT_CONFIGURED",
|
|
567
|
+
"STUDIO_RESPONSE_INVALID",
|
|
568
|
+
"EVAL_CONCURRENCY_CHANGED",
|
|
569
|
+
"EVAL_CONSUMER_FAILED",
|
|
570
|
+
"EVAL_CONTRACT_CHANGED",
|
|
571
|
+
"EVAL_DISCOVERY_REJECTED",
|
|
572
|
+
"EVAL_EXECUTION_CONFLICT",
|
|
573
|
+
"EVAL_EXECUTION_STORE_CHANGED",
|
|
574
|
+
"EVAL_EXECUTION_UNKNOWN",
|
|
575
|
+
"EVAL_EXECUTOR_BUSY",
|
|
576
|
+
"EVAL_EXECUTOR_FAILED",
|
|
577
|
+
"EVAL_EXECUTOR_REJECTED",
|
|
578
|
+
"EVAL_EXECUTOR_UNAUTHORIZED",
|
|
579
|
+
"EVAL_GRADING_FAILED",
|
|
580
|
+
"EVAL_GRADING_TIMEOUT",
|
|
581
|
+
"EVAL_JUDGE_UNAVAILABLE",
|
|
582
|
+
"EVAL_LEASE_LOST",
|
|
583
|
+
"EVAL_RETRY_DELAY_EXCEEDED",
|
|
584
|
+
"EVAL_SETUP_TIMEOUT",
|
|
585
|
+
"EVAL_TRANSPORT_UNAVAILABLE",
|
|
586
|
+
"EVAL_VERIFICATION_TIMEOUT",
|
|
587
|
+
"EVAL_RESULT_INVALID",
|
|
588
|
+
"EVAL_RUN_TIMEOUT",
|
|
589
|
+
"EVAL_SETTINGS_INVALID",
|
|
291
590
|
"EXECUTION_FAILED",
|
|
292
591
|
"INVALID_REQUEST",
|
|
293
592
|
"INVALID_RESUME",
|
|
@@ -355,8 +654,8 @@ function scale(value) {
|
|
|
355
654
|
return value <= 1 ? "1" : value <= 5 ? "2-5" : value <= 20 ? "6-20" : value <= 100 ? "21-100" : "101+";
|
|
356
655
|
}
|
|
357
656
|
|
|
358
|
-
// src/
|
|
359
|
-
function
|
|
657
|
+
// src/failure.ts
|
|
658
|
+
function usageErrorProperty(value, key) {
|
|
360
659
|
try {
|
|
361
660
|
if (!value || typeof value !== "object") return void 0;
|
|
362
661
|
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
@@ -365,40 +664,201 @@ function property(value, key) {
|
|
|
365
664
|
return void 0;
|
|
366
665
|
}
|
|
367
666
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
667
|
+
var networkCodes = {
|
|
668
|
+
ENOTFOUND: "NETWORK_DNS_FAILED",
|
|
669
|
+
EAI_AGAIN: "NETWORK_DNS_FAILED",
|
|
670
|
+
ECONNREFUSED: "NETWORK_CONNECTION_REFUSED",
|
|
671
|
+
ECONNRESET: "NETWORK_CONNECTION_RESET",
|
|
672
|
+
EPIPE: "NETWORK_CONNECTION_RESET",
|
|
673
|
+
ETIMEDOUT: "NETWORK_TIMEOUT",
|
|
674
|
+
UND_ERR_CONNECT_TIMEOUT: "NETWORK_TIMEOUT",
|
|
675
|
+
UND_ERR_HEADERS_TIMEOUT: "NETWORK_TIMEOUT",
|
|
676
|
+
UND_ERR_BODY_TIMEOUT: "NETWORK_TIMEOUT",
|
|
677
|
+
CERT_HAS_EXPIRED: "NETWORK_TLS_FAILED",
|
|
678
|
+
DEPTH_ZERO_SELF_SIGNED_CERT: "NETWORK_TLS_FAILED",
|
|
679
|
+
UNABLE_TO_VERIFY_LEAF_SIGNATURE: "NETWORK_TLS_FAILED"
|
|
680
|
+
};
|
|
681
|
+
function classifyUsageHttpStatus(status) {
|
|
682
|
+
if (!Number.isInteger(status) || status < 100 || status > 599)
|
|
683
|
+
return {
|
|
684
|
+
outcome: "failed",
|
|
685
|
+
properties: {
|
|
686
|
+
error_code: "UNCLASSIFIED_FAILURE",
|
|
687
|
+
error_category: "unknown"
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
if (status < 400)
|
|
691
|
+
return {
|
|
692
|
+
outcome: "success",
|
|
693
|
+
properties: { http_status_class: `${Math.floor(status / 100)}xx` }
|
|
694
|
+
};
|
|
695
|
+
const code = status === 401 ? "HTTP_UNAUTHORIZED" : status === 403 ? "HTTP_FORBIDDEN" : status === 404 ? "HTTP_NOT_FOUND" : status === 408 || status === 504 ? "HTTP_TIMEOUT" : status === 409 ? "HTTP_CONFLICT" : status === 413 ? "HTTP_TOO_LARGE" : status === 429 ? "HTTP_RATE_LIMITED" : status >= 500 ? "HTTP_SERVER_ERROR" : "HTTP_INVALID_REQUEST";
|
|
696
|
+
return {
|
|
697
|
+
outcome: "failed",
|
|
698
|
+
properties: {
|
|
699
|
+
error_code: code,
|
|
700
|
+
error_category: status >= 500 || status === 408 ? "transport" : "request",
|
|
701
|
+
http_status: String(status),
|
|
702
|
+
http_status_class: `${Math.floor(status / 100)}xx`,
|
|
703
|
+
retryable: status === 408 || status === 429 || status >= 500
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
function nativeExceptionName(value) {
|
|
708
|
+
try {
|
|
709
|
+
if (typeof DOMException !== "undefined")
|
|
710
|
+
return Object.getOwnPropertyDescriptor(
|
|
711
|
+
DOMException.prototype,
|
|
712
|
+
"name"
|
|
713
|
+
)?.get?.call(value);
|
|
714
|
+
} catch {
|
|
715
|
+
}
|
|
716
|
+
return void 0;
|
|
717
|
+
}
|
|
718
|
+
function classifyOne(error, catalog) {
|
|
719
|
+
const read = (key) => usageErrorProperty(error, key);
|
|
720
|
+
let name = read("name") ?? nativeExceptionName(error);
|
|
721
|
+
try {
|
|
722
|
+
if (name === void 0 && error instanceof SyntaxError)
|
|
723
|
+
name = "SyntaxError";
|
|
724
|
+
} catch {
|
|
725
|
+
}
|
|
726
|
+
const code = read("code");
|
|
727
|
+
if (name === "AbortError" || code === "EXECUTION_CANCELLED" || code === "ABORT_ERR")
|
|
372
728
|
return { outcome: "cancelled", properties: {} };
|
|
373
729
|
if (code === "EXECUTION_LIMIT_REACHED" || name === "ExecutionLimitReached")
|
|
374
730
|
return { outcome: "limit_reached", properties: {} };
|
|
375
|
-
if (
|
|
731
|
+
if (typeof name === "string" && [
|
|
732
|
+
"GraphInterrupt",
|
|
733
|
+
"NodeInterrupt",
|
|
734
|
+
"Interrupt",
|
|
735
|
+
"ParallelChildWaiting"
|
|
736
|
+
].includes(name))
|
|
376
737
|
return { outcome: "suspended", properties: {} };
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
738
|
+
if (name === "EvalConfigurationError")
|
|
739
|
+
return {
|
|
740
|
+
outcome: "failed",
|
|
741
|
+
properties: {
|
|
742
|
+
error_code: "EVAL_SETTINGS_INVALID",
|
|
743
|
+
error_category: "configuration",
|
|
744
|
+
retryable: false
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
if (name === "TimeoutError")
|
|
748
|
+
return {
|
|
749
|
+
outcome: "failed",
|
|
750
|
+
properties: {
|
|
751
|
+
error_code: "NETWORK_TIMEOUT",
|
|
752
|
+
error_category: "transport",
|
|
753
|
+
retryable: true
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
if (typeof code === "string" && Object.hasOwn(networkCodes, code))
|
|
757
|
+
return {
|
|
758
|
+
outcome: "failed",
|
|
759
|
+
properties: {
|
|
760
|
+
error_code: networkCodes[code] ?? "UNCLASSIFIED_FAILURE",
|
|
761
|
+
error_category: "transport",
|
|
762
|
+
retryable: true
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
if (typeof code === "string" && catalog.errorCodes.includes(code)) {
|
|
766
|
+
const failure = usageErrorProperty(error, "failure");
|
|
767
|
+
const category = read("category") ?? usageErrorProperty(failure, "category");
|
|
768
|
+
const retryable = read("retryable") ?? usageErrorProperty(failure, "retryable");
|
|
769
|
+
const status2 = read("status") ?? usageErrorProperty(failure, "status");
|
|
770
|
+
return {
|
|
771
|
+
outcome: "failed",
|
|
772
|
+
properties: {
|
|
773
|
+
...typeof status2 === "number" ? classifyUsageHttpStatus(status2).properties : {},
|
|
774
|
+
// The framework code is more specific than its HTTP projection.
|
|
775
|
+
error_code: code,
|
|
776
|
+
error_category: code !== "EXECUTION_FAILED" && typeof category === "string" && Array.isArray(catalog.properties.error_category) && catalog.properties.error_category.includes(category) ? category : "unknown",
|
|
777
|
+
...typeof retryable === "boolean" ? { retryable } : {}
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
const status = read("status") ?? read("statusCode");
|
|
782
|
+
if (typeof status === "number" && Number.isInteger(status) && status >= 400 && status <= 599)
|
|
783
|
+
return classifyUsageHttpStatus(status);
|
|
784
|
+
if (name === "ZodError" || name === "SyntaxError")
|
|
785
|
+
return {
|
|
786
|
+
outcome: "failed",
|
|
787
|
+
properties: {
|
|
788
|
+
error_code: "SCHEMA_VALIDATION",
|
|
789
|
+
error_category: "validation"
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
return void 0;
|
|
793
|
+
}
|
|
794
|
+
function classifyUsageError(error, catalog = publicCatalog) {
|
|
795
|
+
const seen = /* @__PURE__ */ new Set();
|
|
796
|
+
const pending = [{ value: error, depth: 0 }];
|
|
797
|
+
let result;
|
|
798
|
+
while (pending.length && seen.size < 8) {
|
|
799
|
+
const current = pending.shift();
|
|
800
|
+
if (!current || seen.has(current.value)) continue;
|
|
801
|
+
seen.add(current.value);
|
|
802
|
+
const found = classifyOne(current.value, catalog);
|
|
803
|
+
if (found) {
|
|
804
|
+
if (!result) result = found;
|
|
805
|
+
else if (found.properties.error_code && found.outcome === "failed" && found.properties.error_code !== result.properties.error_code) {
|
|
806
|
+
result.properties.cause_code = found.properties.error_code;
|
|
807
|
+
result.properties.cause_category = found.properties.error_category ?? "unknown";
|
|
808
|
+
if (result.properties.retryable === void 0 && typeof found.properties.retryable === "boolean")
|
|
809
|
+
result.properties.retryable = found.properties.retryable;
|
|
810
|
+
break;
|
|
811
|
+
}
|
|
812
|
+
if (result === found && found.outcome !== "failed") return found;
|
|
386
813
|
}
|
|
814
|
+
if (current.depth < 3)
|
|
815
|
+
for (const key of ["failure", "cause", "error"]) {
|
|
816
|
+
const value = usageErrorProperty(current.value, key);
|
|
817
|
+
if (value && typeof value === "object")
|
|
818
|
+
pending.push({ value, depth: current.depth + 1 });
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return result ?? {
|
|
822
|
+
outcome: "failed",
|
|
823
|
+
properties: { error_code: "other", error_category: "unknown" }
|
|
387
824
|
};
|
|
388
825
|
}
|
|
826
|
+
|
|
827
|
+
// src/measurement.ts
|
|
828
|
+
function usageMeasurement(event, operation, input) {
|
|
829
|
+
if (event === "usage.feature")
|
|
830
|
+
return usageErrorProperty(input, "origin") === "background" || usageErrorProperty(input, "origin") === "server" ? "observation" : "feature";
|
|
831
|
+
if (operation === "cli.command" || operation === "sdk.eval")
|
|
832
|
+
return "invocation";
|
|
833
|
+
if (operation === "studio.setup") return "stage";
|
|
834
|
+
if (operation === "sdk.execution" || operation === "studio.eval.execution")
|
|
835
|
+
return "execution";
|
|
836
|
+
if (operation === "sdk.export" || operation === "sdk.model") return "attempt";
|
|
837
|
+
if (operation === "sdk.structured") {
|
|
838
|
+
const format = usageErrorProperty(input, "format");
|
|
839
|
+
return format === "text-delta" ? "chunk" : format === "final" ? "output" : "update";
|
|
840
|
+
}
|
|
841
|
+
if (usageErrorProperty(input, "origin") === "background") return "poll";
|
|
842
|
+
if (operation.startsWith("studio.")) return "request";
|
|
843
|
+
return "call";
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// src/client.ts
|
|
389
847
|
function sanitizeProperties(input, catalog = publicCatalog) {
|
|
390
848
|
const safe = {};
|
|
391
849
|
for (const [key, rule] of Object.entries(catalog.properties)) {
|
|
392
|
-
const value =
|
|
850
|
+
const value = usageErrorProperty(input, key);
|
|
393
851
|
if (value === void 0) continue;
|
|
394
852
|
if (rule === "boolean") {
|
|
395
853
|
if (typeof value === "boolean") safe[key] = value;
|
|
396
854
|
} else if (typeof value === "string")
|
|
397
855
|
safe[key] = rule.includes(value) ? value : "other";
|
|
398
856
|
}
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
857
|
+
for (const key of ["error_code", "cause_code"]) {
|
|
858
|
+
const code = usageErrorProperty(input, key);
|
|
859
|
+
if (typeof code === "string")
|
|
860
|
+
safe[key] = catalog.errorCodes.includes(code) ? code : "other";
|
|
861
|
+
}
|
|
402
862
|
return safe;
|
|
403
863
|
}
|
|
404
864
|
var durationBounds = [10, 100, 1e3, 1e4, 6e4];
|
|
@@ -419,6 +879,16 @@ function createUsageTelemetry(options) {
|
|
|
419
879
|
let disposed = false;
|
|
420
880
|
let dropped = 0;
|
|
421
881
|
let delivered = 0;
|
|
882
|
+
let lostObservations = 0;
|
|
883
|
+
let failedBatches = 0;
|
|
884
|
+
let reportedLoss = 0;
|
|
885
|
+
let reportedFailures = 0;
|
|
886
|
+
const lose = (count) => {
|
|
887
|
+
lostObservations = Math.min(
|
|
888
|
+
Number.MAX_SAFE_INTEGER,
|
|
889
|
+
lostObservations + count
|
|
890
|
+
);
|
|
891
|
+
};
|
|
422
892
|
let hour = Math.floor(now() / 36e5);
|
|
423
893
|
let sent = 0;
|
|
424
894
|
const active = () => {
|
|
@@ -454,6 +924,10 @@ function createUsageTelemetry(options) {
|
|
|
454
924
|
pending.clear();
|
|
455
925
|
if (!records.length) return;
|
|
456
926
|
let attempted = records.length;
|
|
927
|
+
let attemptedObservations = records.reduce(
|
|
928
|
+
(total, record2) => total + record2.count,
|
|
929
|
+
0
|
|
930
|
+
);
|
|
457
931
|
flight = (async () => {
|
|
458
932
|
try {
|
|
459
933
|
if (options.debug?.()) {
|
|
@@ -471,7 +945,14 @@ function createUsageTelemetry(options) {
|
|
|
471
945
|
);
|
|
472
946
|
const batch = records.slice(0, allowance);
|
|
473
947
|
dropped += records.length - batch.length;
|
|
948
|
+
lose(
|
|
949
|
+
records.slice(allowance).reduce((total, record2) => total + record2.count, 0)
|
|
950
|
+
);
|
|
474
951
|
attempted = batch.length;
|
|
952
|
+
attemptedObservations = batch.reduce(
|
|
953
|
+
(total, record2) => total + record2.count,
|
|
954
|
+
0
|
|
955
|
+
);
|
|
475
956
|
if (!batch.length || !active()) return;
|
|
476
957
|
const identified = await options.identity();
|
|
477
958
|
const identity = typeof identified === "string" ? identified : identified.id;
|
|
@@ -482,13 +963,25 @@ function createUsageTelemetry(options) {
|
|
|
482
963
|
identity
|
|
483
964
|
)) {
|
|
484
965
|
dropped += batch.length;
|
|
966
|
+
lose(attemptedObservations);
|
|
485
967
|
return;
|
|
486
968
|
}
|
|
487
969
|
sent += batch.length;
|
|
970
|
+
const lossSnapshot = lostObservations;
|
|
971
|
+
const failureSnapshot = failedBatches;
|
|
972
|
+
if (batch[0] && (lossSnapshot > reportedLoss || failureSnapshot > reportedFailures))
|
|
973
|
+
batch[0].delivery_health = {
|
|
974
|
+
dropped_observations: lossSnapshot - reportedLoss,
|
|
975
|
+
failed_batches: failureSnapshot - reportedFailures
|
|
976
|
+
};
|
|
488
977
|
await options.transport(batch, identity);
|
|
978
|
+
reportedLoss = lossSnapshot;
|
|
979
|
+
reportedFailures = failureSnapshot;
|
|
489
980
|
delivered += batch.length;
|
|
490
981
|
} catch {
|
|
491
982
|
dropped += attempted;
|
|
983
|
+
lose(attemptedObservations);
|
|
984
|
+
failedBatches = Math.min(Number.MAX_SAFE_INTEGER, failedBatches + 1);
|
|
492
985
|
}
|
|
493
986
|
})().finally(() => {
|
|
494
987
|
flight = void 0;
|
|
@@ -512,12 +1005,29 @@ function createUsageTelemetry(options) {
|
|
|
512
1005
|
}
|
|
513
1006
|
if (!configured || !catalog.operations.includes(operation) || !outcomes.includes(outcome))
|
|
514
1007
|
return;
|
|
515
|
-
const
|
|
1008
|
+
const failed = outcome === "failed";
|
|
1009
|
+
const status = usageErrorProperty(input, "http_status");
|
|
1010
|
+
const http = typeof status === "string" && /^\d{3}$/.test(status) ? classifyUsageHttpStatus(Number(status)).properties : {};
|
|
1011
|
+
const properties = sanitizeProperties(
|
|
1012
|
+
{
|
|
1013
|
+
measurement_version: "2",
|
|
1014
|
+
measurement_kind: usageMeasurement(event, operation, input),
|
|
1015
|
+
...failed ? {
|
|
1016
|
+
error_code: "UNCLASSIFIED_FAILURE",
|
|
1017
|
+
error_category: "unknown",
|
|
1018
|
+
...http
|
|
1019
|
+
} : {},
|
|
1020
|
+
...sanitizeProperties(input, catalog),
|
|
1021
|
+
traffic_source: options.context.trafficSource ?? "unknown"
|
|
1022
|
+
},
|
|
1023
|
+
catalog
|
|
1024
|
+
);
|
|
516
1025
|
const key = JSON.stringify([event, operation, outcome, properties]);
|
|
517
1026
|
let existing = pending.get(key);
|
|
518
1027
|
if (!existing) {
|
|
519
1028
|
if (pending.size >= (options.maxGroups ?? 64)) {
|
|
520
1029
|
dropped++;
|
|
1030
|
+
lose(1);
|
|
521
1031
|
return;
|
|
522
1032
|
}
|
|
523
1033
|
existing = {
|
|
@@ -529,7 +1039,9 @@ function createUsageTelemetry(options) {
|
|
|
529
1039
|
component: options.context.component,
|
|
530
1040
|
version: options.context.version,
|
|
531
1041
|
analytics_environment: options.context.environment ?? "production",
|
|
532
|
-
runtime_mode:
|
|
1042
|
+
runtime_mode: ["development", "production", "ci"].includes(
|
|
1043
|
+
options.context.runtimeMode ?? ""
|
|
1044
|
+
) ? options.context.runtimeMode ?? "unknown" : "unknown",
|
|
533
1045
|
identity_scope: options.context.identityScope ?? "installation",
|
|
534
1046
|
operation,
|
|
535
1047
|
outcome,
|
|
@@ -574,8 +1086,11 @@ function createUsageTelemetry(options) {
|
|
|
574
1086
|
if (ended) return;
|
|
575
1087
|
ended = true;
|
|
576
1088
|
try {
|
|
1089
|
+
const status = usageErrorProperty(extra, "http_status");
|
|
1090
|
+
const http = outcome === "failed" && typeof status === "string" && /^\d{3}$/.test(status) ? classifyUsageHttpStatus(Number(status)).properties : {};
|
|
577
1091
|
record("usage.operation", operation, outcome, now() - began, {
|
|
578
1092
|
...initial,
|
|
1093
|
+
...http,
|
|
579
1094
|
...sanitizeProperties(extra, catalog)
|
|
580
1095
|
});
|
|
581
1096
|
} catch {
|
|
@@ -658,6 +1173,10 @@ function createPostHogTransport(options) {
|
|
|
658
1173
|
count: record.count,
|
|
659
1174
|
duration_total_ms: record.duration_total_ms,
|
|
660
1175
|
duration_buckets: record.duration_buckets,
|
|
1176
|
+
...record.delivery_health ? {
|
|
1177
|
+
usage_dropped_observations: record.delivery_health.dropped_observations,
|
|
1178
|
+
usage_failed_batches: record.delivery_health.failed_batches
|
|
1179
|
+
} : {},
|
|
661
1180
|
$process_person_profile: false,
|
|
662
1181
|
$geoip_disable: true,
|
|
663
1182
|
$ip: null
|
|
@@ -712,6 +1231,7 @@ function createCollectorTransport(options) {
|
|
|
712
1231
|
// Annotate the CommonJS export names for ESM import in node:
|
|
713
1232
|
0 && (module.exports = {
|
|
714
1233
|
classifyUsageError,
|
|
1234
|
+
classifyUsageHttpStatus,
|
|
715
1235
|
createCollectorTransport,
|
|
716
1236
|
createPostHogTransport,
|
|
717
1237
|
createUsageTelemetry,
|