@aexhq/sdk 0.46.5-canary → 0.51.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.
Files changed (346) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +38 -0
  3. package/README.md +54 -29
  4. package/dist/client/aex.d.ts +33 -0
  5. package/dist/client/aex.js +108 -0
  6. package/dist/client/aex.js.map +1 -0
  7. package/dist/client/credentials.d.ts +25 -0
  8. package/dist/client/credentials.js +97 -0
  9. package/dist/client/credentials.js.map +1 -0
  10. package/dist/client/routing.d.ts +7 -0
  11. package/dist/client/routing.js +29 -0
  12. package/dist/client/routing.js.map +1 -0
  13. package/dist/downloads/download.d.ts +18 -0
  14. package/dist/downloads/download.js +67 -0
  15. package/dist/downloads/download.js.map +1 -0
  16. package/dist/generated/errors.d.ts +12 -0
  17. package/dist/generated/errors.js +82 -0
  18. package/dist/generated/errors.js.map +1 -0
  19. package/dist/generated/models.d.ts +1392 -0
  20. package/dist/generated/models.js +62 -0
  21. package/dist/generated/models.js.map +1 -0
  22. package/dist/generated/resources.d.ts +710 -0
  23. package/dist/generated/resources.js +582 -0
  24. package/dist/generated/resources.js.map +1 -0
  25. package/dist/generated/routes.d.ts +44 -0
  26. package/dist/generated/routes.js +1905 -0
  27. package/dist/generated/routes.js.map +1 -0
  28. package/dist/index.d.ts +21 -50
  29. package/dist/index.js +14 -62
  30. package/dist/index.js.map +1 -1
  31. package/dist/node/session-file-limits.d.ts +4 -0
  32. package/dist/node/session-file-limits.js +7 -0
  33. package/dist/node/session-file-limits.js.map +1 -0
  34. package/dist/node/session-files.d.ts +80 -0
  35. package/dist/node/session-files.js +254 -0
  36. package/dist/node/session-files.js.map +1 -0
  37. package/dist/observations/stream.d.ts +1 -0
  38. package/dist/observations/stream.js +18 -0
  39. package/dist/observations/stream.js.map +1 -0
  40. package/dist/transport/errors.d.ts +60 -0
  41. package/dist/transport/errors.js +107 -0
  42. package/dist/transport/errors.js.map +1 -0
  43. package/dist/transport/pagination.d.ts +8 -0
  44. package/dist/transport/pagination.js +34 -0
  45. package/dist/transport/pagination.js.map +1 -0
  46. package/dist/transport/retry.d.ts +21 -0
  47. package/dist/transport/retry.js +37 -0
  48. package/dist/transport/retry.js.map +1 -0
  49. package/dist/transport/transport.d.ts +25 -0
  50. package/dist/transport/transport.js +33 -0
  51. package/dist/transport/transport.js.map +1 -0
  52. package/package.json +67 -30
  53. package/dist/_contracts/account-operations.d.ts +0 -101
  54. package/dist/_contracts/account-operations.js +0 -242
  55. package/dist/_contracts/account-types.d.ts +0 -461
  56. package/dist/_contracts/account-types.js +0 -1
  57. package/dist/_contracts/api-key.d.ts +0 -61
  58. package/dist/_contracts/api-key.js +0 -101
  59. package/dist/_contracts/api-routes.d.ts +0 -20
  60. package/dist/_contracts/api-routes.js +0 -109
  61. package/dist/_contracts/archive-limits.d.ts +0 -3
  62. package/dist/_contracts/archive-limits.js +0 -23
  63. package/dist/_contracts/asset-authoring.d.ts +0 -22
  64. package/dist/_contracts/asset-authoring.js +0 -106
  65. package/dist/_contracts/asset-bundle.d.ts +0 -64
  66. package/dist/_contracts/asset-bundle.js +0 -263
  67. package/dist/_contracts/asset-upload-helper.d.ts +0 -31
  68. package/dist/_contracts/asset-upload-helper.js +0 -84
  69. package/dist/_contracts/billing-admission.d.ts +0 -29
  70. package/dist/_contracts/billing-admission.js +0 -28
  71. package/dist/_contracts/bundle-manifest.d.ts +0 -89
  72. package/dist/_contracts/bundle-manifest.js +0 -158
  73. package/dist/_contracts/canonical-sha256.d.ts +0 -8
  74. package/dist/_contracts/canonical-sha256.js +0 -8
  75. package/dist/_contracts/connection-ticket.d.ts +0 -22
  76. package/dist/_contracts/connection-ticket.js +0 -54
  77. package/dist/_contracts/continuation-event.d.ts +0 -31
  78. package/dist/_contracts/continuation-event.js +0 -6
  79. package/dist/_contracts/contract-parse-error.d.ts +0 -12
  80. package/dist/_contracts/contract-parse-error.js +0 -51
  81. package/dist/_contracts/error-codes.d.ts +0 -26
  82. package/dist/_contracts/error-codes.js +0 -116
  83. package/dist/_contracts/error-factory.d.ts +0 -32
  84. package/dist/_contracts/error-factory.js +0 -174
  85. package/dist/_contracts/event-envelope.d.ts +0 -471
  86. package/dist/_contracts/event-envelope.js +0 -501
  87. package/dist/_contracts/event-stream-client.d.ts +0 -122
  88. package/dist/_contracts/event-stream-client.js +0 -445
  89. package/dist/_contracts/event-view.d.ts +0 -44
  90. package/dist/_contracts/event-view.js +0 -69
  91. package/dist/_contracts/failure-class.d.ts +0 -29
  92. package/dist/_contracts/failure-class.js +0 -73
  93. package/dist/_contracts/http.d.ts +0 -135
  94. package/dist/_contracts/http.js +0 -434
  95. package/dist/_contracts/ids.d.ts +0 -66
  96. package/dist/_contracts/ids.js +0 -119
  97. package/dist/_contracts/index.d.ts +0 -42
  98. package/dist/_contracts/index.js +0 -52
  99. package/dist/_contracts/internal.d.ts +0 -55
  100. package/dist/_contracts/internal.js +0 -113
  101. package/dist/_contracts/models.d.ts +0 -30
  102. package/dist/_contracts/models.js +0 -28
  103. package/dist/_contracts/operation-core.d.ts +0 -36
  104. package/dist/_contracts/operation-core.js +0 -70
  105. package/dist/_contracts/operations.d.ts +0 -218
  106. package/dist/_contracts/operations.js +0 -1496
  107. package/dist/_contracts/otlp-projection.d.ts +0 -78
  108. package/dist/_contracts/otlp-projection.js +0 -171
  109. package/dist/_contracts/post-hook.d.ts +0 -31
  110. package/dist/_contracts/post-hook.js +0 -61
  111. package/dist/_contracts/provider-fault.d.ts +0 -34
  112. package/dist/_contracts/provider-fault.js +0 -68
  113. package/dist/_contracts/retry-core.d.ts +0 -29
  114. package/dist/_contracts/retry-core.js +0 -79
  115. package/dist/_contracts/runner-event.d.ts +0 -117
  116. package/dist/_contracts/runner-event.js +0 -172
  117. package/dist/_contracts/runtime-kind.d.ts +0 -60
  118. package/dist/_contracts/runtime-kind.js +0 -70
  119. package/dist/_contracts/runtime-manifest.d.ts +0 -121
  120. package/dist/_contracts/runtime-manifest.js +0 -83
  121. package/dist/_contracts/runtime-security-profile.d.ts +0 -26
  122. package/dist/_contracts/runtime-security-profile.js +0 -73
  123. package/dist/_contracts/runtime-sizes.d.ts +0 -104
  124. package/dist/_contracts/runtime-sizes.js +0 -111
  125. package/dist/_contracts/runtime-types.d.ts +0 -618
  126. package/dist/_contracts/runtime-types.js +0 -58
  127. package/dist/_contracts/schemas/asset-bundle.d.ts +0 -70
  128. package/dist/_contracts/schemas/asset-bundle.js +0 -107
  129. package/dist/_contracts/schemas/asset-ref.d.ts +0 -61
  130. package/dist/_contracts/schemas/asset-ref.js +0 -118
  131. package/dist/_contracts/schemas/bundle-manifest.d.ts +0 -66
  132. package/dist/_contracts/schemas/bundle-manifest.js +0 -77
  133. package/dist/_contracts/schemas/index.d.ts +0 -32
  134. package/dist/_contracts/schemas/index.js +0 -30
  135. package/dist/_contracts/schemas/mcp-server.d.ts +0 -99
  136. package/dist/_contracts/schemas/mcp-server.js +0 -209
  137. package/dist/_contracts/schemas/models.d.ts +0 -29
  138. package/dist/_contracts/schemas/models.js +0 -51
  139. package/dist/_contracts/schemas/numeric.d.ts +0 -18
  140. package/dist/_contracts/schemas/numeric.js +0 -28
  141. package/dist/_contracts/schemas/post-hook.d.ts +0 -45
  142. package/dist/_contracts/schemas/post-hook.js +0 -68
  143. package/dist/_contracts/schemas/response-assets.d.ts +0 -75
  144. package/dist/_contracts/schemas/response-assets.js +0 -81
  145. package/dist/_contracts/schemas/response-billing.d.ts +0 -208
  146. package/dist/_contracts/schemas/response-billing.js +0 -139
  147. package/dist/_contracts/schemas/response-common.d.ts +0 -132
  148. package/dist/_contracts/schemas/response-common.js +0 -162
  149. package/dist/_contracts/schemas/response-identity.d.ts +0 -648
  150. package/dist/_contracts/schemas/response-identity.js +0 -131
  151. package/dist/_contracts/schemas/response-mcp-servers.d.ts +0 -51
  152. package/dist/_contracts/schemas/response-mcp-servers.js +0 -32
  153. package/dist/_contracts/schemas/response-secrets.d.ts +0 -50
  154. package/dist/_contracts/schemas/response-secrets.js +0 -32
  155. package/dist/_contracts/schemas/response-sessions-internal.d.ts +0 -200
  156. package/dist/_contracts/schemas/response-sessions-internal.js +0 -142
  157. package/dist/_contracts/schemas/response-sessions.d.ts +0 -1598
  158. package/dist/_contracts/schemas/response-sessions.js +0 -377
  159. package/dist/_contracts/schemas/response-webhooks.d.ts +0 -76
  160. package/dist/_contracts/schemas/response-webhooks.js +0 -42
  161. package/dist/_contracts/schemas/response-workspace.d.ts +0 -225
  162. package/dist/_contracts/schemas/response-workspace.js +0 -99
  163. package/dist/_contracts/schemas/runtime-kind.d.ts +0 -31
  164. package/dist/_contracts/schemas/runtime-kind.js +0 -29
  165. package/dist/_contracts/schemas/runtime-security-profile.d.ts +0 -28
  166. package/dist/_contracts/schemas/runtime-security-profile.js +0 -26
  167. package/dist/_contracts/schemas/runtime-sizes.d.ts +0 -70
  168. package/dist/_contracts/schemas/runtime-sizes.js +0 -127
  169. package/dist/_contracts/schemas/session-limits.d.ts +0 -34
  170. package/dist/_contracts/schemas/session-limits.js +0 -39
  171. package/dist/_contracts/schemas/session-machine.d.ts +0 -23
  172. package/dist/_contracts/schemas/session-machine.js +0 -24
  173. package/dist/_contracts/schemas/session-request-config.d.ts +0 -58
  174. package/dist/_contracts/schemas/session-request-config.js +0 -134
  175. package/dist/_contracts/schemas/session-webhook.d.ts +0 -11
  176. package/dist/_contracts/schemas/session-webhook.js +0 -38
  177. package/dist/_contracts/schemas/side-effect-audit.d.ts +0 -98
  178. package/dist/_contracts/schemas/side-effect-audit.js +0 -102
  179. package/dist/_contracts/schemas/submission-assets.d.ts +0 -117
  180. package/dist/_contracts/schemas/submission-assets.js +0 -147
  181. package/dist/_contracts/schemas/submission-body.d.ts +0 -251
  182. package/dist/_contracts/schemas/submission-body.js +0 -378
  183. package/dist/_contracts/schemas/submission-environment.d.ts +0 -79
  184. package/dist/_contracts/schemas/submission-environment.js +0 -179
  185. package/dist/_contracts/schemas/submission-request.d.ts +0 -158
  186. package/dist/_contracts/schemas/submission-request.js +0 -49
  187. package/dist/_contracts/schemas/submission-secrets.d.ts +0 -47
  188. package/dist/_contracts/schemas/submission-secrets.js +0 -108
  189. package/dist/_contracts/schemas/wire.d.ts +0 -118
  190. package/dist/_contracts/schemas/wire.js +0 -171
  191. package/dist/_contracts/schemas/workspace-resources.d.ts +0 -50
  192. package/dist/_contracts/schemas/workspace-resources.js +0 -87
  193. package/dist/_contracts/sdk-errors.d.ts +0 -212
  194. package/dist/_contracts/sdk-errors.js +0 -313
  195. package/dist/_contracts/sdk-secrets.d.ts +0 -67
  196. package/dist/_contracts/sdk-secrets.js +0 -427
  197. package/dist/_contracts/session-archive.d.ts +0 -16
  198. package/dist/_contracts/session-archive.js +0 -92
  199. package/dist/_contracts/session-artifacts.d.ts +0 -189
  200. package/dist/_contracts/session-artifacts.js +0 -264
  201. package/dist/_contracts/session-config.d.ts +0 -373
  202. package/dist/_contracts/session-config.js +0 -562
  203. package/dist/_contracts/session-cost-types.d.ts +0 -211
  204. package/dist/_contracts/session-cost-types.js +0 -69
  205. package/dist/_contracts/session-cost.d.ts +0 -8
  206. package/dist/_contracts/session-cost.js +0 -582
  207. package/dist/_contracts/session-custody.d.ts +0 -165
  208. package/dist/_contracts/session-custody.js +0 -345
  209. package/dist/_contracts/session-file-query.d.ts +0 -14
  210. package/dist/_contracts/session-file-query.js +0 -178
  211. package/dist/_contracts/session-record.d.ts +0 -112
  212. package/dist/_contracts/session-record.js +0 -165
  213. package/dist/_contracts/session-retention.d.ts +0 -201
  214. package/dist/_contracts/session-retention.js +0 -450
  215. package/dist/_contracts/side-effect-audit.d.ts +0 -126
  216. package/dist/_contracts/side-effect-audit.js +0 -520
  217. package/dist/_contracts/sse.d.ts +0 -74
  218. package/dist/_contracts/sse.js +0 -227
  219. package/dist/_contracts/stable.d.ts +0 -45
  220. package/dist/_contracts/stable.js +0 -62
  221. package/dist/_contracts/status.d.ts +0 -25
  222. package/dist/_contracts/status.js +0 -57
  223. package/dist/_contracts/submission-limits.d.ts +0 -61
  224. package/dist/_contracts/submission-limits.js +0 -60
  225. package/dist/_contracts/submission.d.ts +0 -547
  226. package/dist/_contracts/submission.js +0 -812
  227. package/dist/_contracts/suggest.d.ts +0 -15
  228. package/dist/_contracts/suggest.js +0 -53
  229. package/dist/_contracts/testing/response-bindings.d.ts +0 -45
  230. package/dist/_contracts/testing/response-bindings.js +0 -256
  231. package/dist/_contracts/testing/wire-conformance-entry.d.ts +0 -10
  232. package/dist/_contracts/testing/wire-conformance-entry.js +0 -8
  233. package/dist/_contracts/testing/wire-conformance.d.ts +0 -169
  234. package/dist/_contracts/testing/wire-conformance.js +0 -276
  235. package/dist/_contracts/turn-trace.d.ts +0 -28
  236. package/dist/_contracts/turn-trace.js +0 -1
  237. package/dist/_contracts/unknown-field-error.d.ts +0 -13
  238. package/dist/_contracts/unknown-field-error.js +0 -21
  239. package/dist/_contracts/value-guards.d.ts +0 -20
  240. package/dist/_contracts/value-guards.js +0 -34
  241. package/dist/_contracts/webhook-verify.d.ts +0 -34
  242. package/dist/_contracts/webhook-verify.js +0 -93
  243. package/dist/_contracts/wire-observer.d.ts +0 -49
  244. package/dist/_contracts/wire-observer.js +0 -34
  245. package/dist/_contracts/workflow-status.d.ts +0 -7
  246. package/dist/_contracts/workflow-status.js +0 -43
  247. package/dist/_contracts/workspace-resources.d.ts +0 -98
  248. package/dist/_contracts/workspace-resources.js +0 -39
  249. package/dist/archive-limits.d.ts +0 -1
  250. package/dist/archive-limits.js +0 -2
  251. package/dist/archive-limits.js.map +0 -1
  252. package/dist/asset-upload.d.ts +0 -47
  253. package/dist/asset-upload.js +0 -269
  254. package/dist/asset-upload.js.map +0 -1
  255. package/dist/bundle.d.ts +0 -9
  256. package/dist/bundle.js +0 -20
  257. package/dist/bundle.js.map +0 -1
  258. package/dist/canonical-zip.d.ts +0 -68
  259. package/dist/canonical-zip.js +0 -355
  260. package/dist/canonical-zip.js.map +0 -1
  261. package/dist/cli.mjs +0 -12048
  262. package/dist/cli.mjs.sha256 +0 -1
  263. package/dist/client-types.d.ts +0 -192
  264. package/dist/client-types.js +0 -2
  265. package/dist/client-types.js.map +0 -1
  266. package/dist/client.d.ts +0 -464
  267. package/dist/client.js +0 -1207
  268. package/dist/client.js.map +0 -1
  269. package/dist/event-projection.d.ts +0 -22
  270. package/dist/event-projection.js +0 -380
  271. package/dist/event-projection.js.map +0 -1
  272. package/dist/fetch-archive.d.ts +0 -16
  273. package/dist/fetch-archive.js +0 -252
  274. package/dist/fetch-archive.js.map +0 -1
  275. package/dist/file.d.ts +0 -96
  276. package/dist/file.js +0 -272
  277. package/dist/file.js.map +0 -1
  278. package/dist/instructions.d.ts +0 -20
  279. package/dist/instructions.js +0 -40
  280. package/dist/instructions.js.map +0 -1
  281. package/dist/legacy-session-provider-fault.d.ts +0 -7
  282. package/dist/legacy-session-provider-fault.js +0 -38
  283. package/dist/legacy-session-provider-fault.js.map +0 -1
  284. package/dist/mcp-server.d.ts +0 -84
  285. package/dist/mcp-server.js +0 -117
  286. package/dist/mcp-server.js.map +0 -1
  287. package/dist/node-fs.d.ts +0 -29
  288. package/dist/node-fs.js +0 -19
  289. package/dist/node-fs.js.map +0 -1
  290. package/dist/node-walk.d.ts +0 -69
  291. package/dist/node-walk.js +0 -151
  292. package/dist/node-walk.js.map +0 -1
  293. package/dist/path-basename.d.ts +0 -5
  294. package/dist/path-basename.js +0 -9
  295. package/dist/path-basename.js.map +0 -1
  296. package/dist/retry.d.ts +0 -70
  297. package/dist/retry.js +0 -155
  298. package/dist/retry.js.map +0 -1
  299. package/dist/secret.d.ts +0 -65
  300. package/dist/secret.js +0 -110
  301. package/dist/secret.js.map +0 -1
  302. package/dist/session-validate.d.ts +0 -100
  303. package/dist/session-validate.js +0 -303
  304. package/dist/session-validate.js.map +0 -1
  305. package/dist/skill.d.ts +0 -99
  306. package/dist/skill.js +0 -169
  307. package/dist/skill.js.map +0 -1
  308. package/dist/submission-wire.d.ts +0 -13
  309. package/dist/submission-wire.js +0 -69
  310. package/dist/submission-wire.js.map +0 -1
  311. package/dist/tool.d.ts +0 -41
  312. package/dist/tool.js +0 -76
  313. package/dist/tool.js.map +0 -1
  314. package/dist/version.d.ts +0 -9
  315. package/dist/version.js +0 -10
  316. package/dist/version.js.map +0 -1
  317. package/docs/authentication.md +0 -125
  318. package/docs/billing.md +0 -164
  319. package/docs/cleanup.md +0 -27
  320. package/docs/concepts/agent-tools.md +0 -47
  321. package/docs/concepts/composition.md +0 -60
  322. package/docs/concepts/providers-and-runtimes.md +0 -121
  323. package/docs/concepts/sessions.md +0 -51
  324. package/docs/concepts/subagents.md +0 -35
  325. package/docs/credentials.md +0 -116
  326. package/docs/defaults.md +0 -51
  327. package/docs/errors.md +0 -258
  328. package/docs/events.md +0 -143
  329. package/docs/files.md +0 -130
  330. package/docs/limits-and-quotas.md +0 -114
  331. package/docs/limits.md +0 -51
  332. package/docs/mcp.md +0 -47
  333. package/docs/networking.md +0 -114
  334. package/docs/provider-runtime-capabilities.md +0 -32
  335. package/docs/public-surface.json +0 -73
  336. package/docs/quickstart.md +0 -135
  337. package/docs/release.md +0 -44
  338. package/docs/retries.md +0 -108
  339. package/docs/secrets.md +0 -141
  340. package/docs/session-config.md +0 -51
  341. package/docs/session-record.md +0 -58
  342. package/docs/skills.md +0 -65
  343. package/docs/telemetry.md +0 -66
  344. package/docs/testing.md +0 -35
  345. package/docs/vision-skills.md +0 -94
  346. package/docs/webhooks.md +0 -143
@@ -1,582 +0,0 @@
1
- import { SESSION_COST_BASIS_STATUSES, SESSION_COST_SUMMARY_STATUSES, SESSION_COST_TELEMETRY_SCHEMA_VERSION, SESSION_USAGE_SAMPLE_METRICS, SESSION_USAGE_SAMPLE_SCHEMA_VERSION, SESSION_USAGE_SAMPLE_SOURCE_TYPES, SESSION_USAGE_SAMPLE_UNITS } from "./session-cost-types.js";
2
- // Keep the named list explicit so the platform mirror gate can follow the source boundary.
3
- export { SESSION_COST_BASIS_STATUSES, SESSION_COST_SUMMARY_STATUSES, SESSION_COST_TELEMETRY_SCHEMA_VERSION, SESSION_USAGE_SAMPLE_METRICS, SESSION_USAGE_SAMPLE_SCHEMA_VERSION, SESSION_USAGE_SAMPLE_SOURCE_TYPES, SESSION_USAGE_SAMPLE_UNITS } from "./session-cost-types.js";
4
- /**
5
- * The unit each metric is denominated in. Module-private: it is an
6
- * implementation detail of {@link buildSessionUsageSample}, which rejects a
7
- * sample whose declared unit disagrees with its metric.
8
- */
9
- const SESSION_USAGE_SAMPLE_METRIC_UNITS = {
10
- "provider.input_tokens": "token",
11
- "provider.output_tokens": "token",
12
- "provider.cache_read_input_tokens": "token",
13
- "provider.cache_creation_input_tokens": "token",
14
- "provider.total_tokens": "token",
15
- "runtime.queued_ms": "millisecond",
16
- "runtime.active_ms": "millisecond",
17
- "runtime.file_capture_ms": "millisecond",
18
- "runtime.cleanup_ms": "millisecond",
19
- "session.total_ms": "millisecond",
20
- "file.discovered_files": "file",
21
- "file.captured_files": "file",
22
- "file.failed_files": "file",
23
- "file.captured_bytes": "byte",
24
- "retry.runtime_attempts": "count",
25
- "retry.provider_poll": "count",
26
- "retry.file_capture": "count",
27
- "retry.file_upload": "count",
28
- "capture.uploaded_files": "file",
29
- "capture.failed_files": "file",
30
- "capture.total_bytes": "byte",
31
- "storage.current_bytes": "byte",
32
- "storage.byte_milliseconds": "byte_millisecond",
33
- "proxy.call_count": "count",
34
- "proxy.failed_call_count": "count",
35
- "proxy.request_bytes": "byte",
36
- "proxy.response_bytes": "byte",
37
- "proxy.duration_ms": "millisecond"
38
- };
39
- export function buildSessionUsageSample(input) {
40
- const metric = normalizeUsageSampleMetric(input.metric);
41
- const expectedUnit = SESSION_USAGE_SAMPLE_METRIC_UNITS[metric];
42
- const unit = input.unit ? normalizeUsageSampleUnit(input.unit) : expectedUnit;
43
- if (unit !== expectedUnit) {
44
- throw new Error(`session usage sample ${metric} must use ${expectedUnit} units`);
45
- }
46
- return Object.freeze({
47
- schemaVersion: SESSION_USAGE_SAMPLE_SCHEMA_VERSION,
48
- ...(input.sampleId ? { sampleId: nonEmptyString(input.sampleId, "sampleId") } : {}),
49
- ...(input.sessionId ? { sessionId: input.sessionId } : {}),
50
- metric,
51
- unit,
52
- quantity: nonNegativeFinite(input.quantity, "quantity"),
53
- source: normalizeUsageSampleSource(input.source),
54
- ...(input.provider ? { provider: input.provider } : {}),
55
- ...(input.model ? { model: input.model } : {}),
56
- ...(input.recordedAt ? { recordedAt: input.recordedAt } : {})
57
- });
58
- }
59
- export function buildSessionCostTelemetry(input) {
60
- return freezeTelemetry({
61
- schemaVersion: SESSION_COST_TELEMETRY_SCHEMA_VERSION,
62
- ...(input.sessionId ? { sessionId: input.sessionId } : {}),
63
- ...(input.provider ? { provider: input.provider } : {}),
64
- ...(input.recordedAt ? { recordedAt: input.recordedAt } : {}),
65
- ...(input.status ? { status: normalizeSummaryStatus(input.status) } : {}),
66
- ...(input.sourceSummary ? { sourceSummary: normalizeSourceSummary(input.sourceSummary) } : {}),
67
- ...(input.durations ? { durations: normalizeDurations(input.durations) } : {}),
68
- ...(input.files ? { files: normalizeFiles(input.files) } : {}),
69
- ...(input.retries ? { retries: normalizeRetries(input.retries) } : {}),
70
- ...(input.capture ? { capture: normalizeCapture(input.capture) } : {}),
71
- ...(input.providerUsage ? { providerUsage: input.providerUsage.map(normalizeProviderUsage) } : {}),
72
- ...(input.storage ? { storage: normalizeStorage(input.storage) } : {}),
73
- ...(input.proxy ? { proxy: normalizeProxy(input.proxy) } : {}),
74
- ...(input.billedCostUsd !== undefined ? { billedCostUsd: nonNegativeFinite(input.billedCostUsd, "billedCostUsd") } : {}),
75
- ...(input.costBasis ? { costBasis: normalizeCostBasis(input.costBasis) } : {}),
76
- // The settle-written half. Carried through rather than dropped: a declared
77
- // field this builder silently discards is worse than an undeclared one,
78
- // because the loss is invisible at the call site.
79
- ...(input.basis ? { basis: nonEmptyString(input.basis, "basis") } : {}),
80
- ...(input.durationMs !== undefined ? { durationMs: nonNegativeFinite(input.durationMs, "durationMs") } : {}),
81
- ...(input.turnSeq !== undefined ? { turnSeq: nonNegativeFinite(input.turnSeq, "turnSeq") } : {}),
82
- ...(input.runtimeSize ? { runtimeSize: nonEmptyString(input.runtimeSize, "runtimeSize") } : {}),
83
- ...(input.runtimeKind ? { runtimeKind: nonEmptyString(input.runtimeKind, "runtimeKind") } : {}),
84
- ...(input.model ? { model: input.model } : {}),
85
- ...(input.usage ? { usage: Object.freeze({ ...input.usage }) } : {}),
86
- ...(input.byteCounts ? { byteCounts: Object.freeze({ ...input.byteCounts }) } : {}),
87
- ...(input.childCostUsd !== undefined
88
- ? { childCostUsd: nonNegativeFinite(input.childCostUsd, "childCostUsd") }
89
- : {}),
90
- ...(input.childSessionCount !== undefined
91
- ? { childSessionCount: nonNegativeFinite(input.childSessionCount, "childSessionCount") }
92
- : {}),
93
- ...(input.childProviderUsage
94
- ? { childProviderUsage: input.childProviderUsage.map(normalizeProviderUsage) }
95
- : {})
96
- });
97
- }
98
- export function buildSessionCostTelemetryFromUsageSamples(input) {
99
- const samples = input.samples.map(buildSessionUsageSample);
100
- const telemetry = {
101
- sourceSummary: summarizeUsageSamples(samples)
102
- };
103
- if (input.sessionId)
104
- telemetry.sessionId = input.sessionId;
105
- if (input.provider)
106
- telemetry.provider = input.provider;
107
- if (input.recordedAt)
108
- telemetry.recordedAt = input.recordedAt;
109
- if (input.status)
110
- telemetry.status = input.status;
111
- const durations = {};
112
- const files = {};
113
- const retries = {};
114
- const capture = {};
115
- const storage = {};
116
- const proxy = {};
117
- const providerUsage = new Map();
118
- let captureAttempted = false;
119
- for (const sample of samples) {
120
- switch (sample.metric) {
121
- case "provider.input_tokens":
122
- addProviderUsage(providerUsage, input, sample, "inputTokens");
123
- break;
124
- case "provider.output_tokens":
125
- addProviderUsage(providerUsage, input, sample, "outputTokens");
126
- break;
127
- case "provider.cache_read_input_tokens":
128
- addProviderUsage(providerUsage, input, sample, "cacheReadInputTokens");
129
- break;
130
- case "provider.cache_creation_input_tokens":
131
- addProviderUsage(providerUsage, input, sample, "cacheCreationInputTokens");
132
- break;
133
- case "provider.total_tokens":
134
- addProviderUsage(providerUsage, input, sample, "totalTokens");
135
- break;
136
- case "runtime.queued_ms":
137
- addDraftNumber(durations, "queuedMs", sample.quantity);
138
- break;
139
- case "runtime.active_ms":
140
- addDraftNumber(durations, "runtimeMs", sample.quantity);
141
- break;
142
- case "runtime.file_capture_ms":
143
- addDraftNumber(durations, "fileCaptureMs", sample.quantity);
144
- break;
145
- case "runtime.cleanup_ms":
146
- addDraftNumber(durations, "cleanupMs", sample.quantity);
147
- break;
148
- case "session.total_ms":
149
- addDraftNumber(durations, "totalMs", sample.quantity);
150
- break;
151
- case "file.discovered_files":
152
- addDraftNumber(files, "discoveredFiles", sample.quantity);
153
- break;
154
- case "file.captured_files":
155
- addDraftNumber(files, "capturedFiles", sample.quantity);
156
- break;
157
- case "file.failed_files":
158
- addDraftNumber(files, "failedFiles", sample.quantity);
159
- break;
160
- case "file.captured_bytes":
161
- addDraftNumber(files, "capturedBytes", sample.quantity);
162
- break;
163
- case "retry.runtime_attempts":
164
- addDraftNumber(retries, "runtimeAttempts", sample.quantity);
165
- break;
166
- case "retry.provider_poll":
167
- addDraftNumber(retries, "providerPollRetries", sample.quantity);
168
- break;
169
- case "retry.file_capture":
170
- addDraftNumber(retries, "fileCaptureRetries", sample.quantity);
171
- break;
172
- case "retry.file_upload":
173
- addDraftNumber(retries, "fileUploadRetries", sample.quantity);
174
- break;
175
- case "capture.uploaded_files":
176
- captureAttempted = true;
177
- addDraftNumber(capture, "uploadedFiles", sample.quantity);
178
- break;
179
- case "capture.failed_files":
180
- captureAttempted = true;
181
- addDraftNumber(capture, "failedFiles", sample.quantity);
182
- break;
183
- case "capture.total_bytes":
184
- captureAttempted = true;
185
- addDraftNumber(capture, "totalBytes", sample.quantity);
186
- break;
187
- case "storage.current_bytes":
188
- addDraftNumber(storage, "storedBytes", sample.quantity);
189
- break;
190
- case "storage.byte_milliseconds":
191
- addDraftNumber(storage, "byteMilliseconds", sample.quantity);
192
- break;
193
- case "proxy.call_count":
194
- addDraftNumber(proxy, "calls", sample.quantity);
195
- break;
196
- case "proxy.failed_call_count":
197
- addDraftNumber(proxy, "failedCalls", sample.quantity);
198
- break;
199
- case "proxy.request_bytes":
200
- addDraftNumber(proxy, "requestBytes", sample.quantity);
201
- break;
202
- case "proxy.response_bytes":
203
- addDraftNumber(proxy, "responseBytes", sample.quantity);
204
- break;
205
- case "proxy.duration_ms":
206
- addDraftNumber(proxy, "durationMs", sample.quantity);
207
- break;
208
- }
209
- }
210
- if (Object.keys(durations).length > 0)
211
- telemetry.durations = durations;
212
- if (Object.keys(files).length > 0)
213
- telemetry.files = files;
214
- if (Object.keys(retries).length > 0)
215
- telemetry.retries = retries;
216
- if (captureAttempted || Object.keys(capture).length > 0) {
217
- telemetry.capture = { attempted: true, ...capture };
218
- }
219
- if (providerUsage.size > 0) {
220
- telemetry.providerUsage = Array.from(providerUsage.values()).map(publicProviderUsage);
221
- }
222
- if (Object.keys(storage).length > 0)
223
- telemetry.storage = storage;
224
- if (Object.keys(proxy).length > 0)
225
- telemetry.proxy = proxy;
226
- return buildSessionCostTelemetry(telemetry);
227
- }
228
- export function summarizeUsageSamples(samples) {
229
- const normalized = samples.map(buildSessionUsageSample);
230
- const metrics = unique(normalized.map((sample) => sample.metric));
231
- const sourceTypes = unique(normalized.map((sample) => sample.source.type));
232
- const sourceSampleIds = unique(normalized.flatMap((sample) => (sample.sampleId ? [sample.sampleId] : [])));
233
- return normalizeSourceSummary({
234
- sampleCount: normalized.length,
235
- ...(metrics.length > 0 ? { metrics } : {}),
236
- ...(sourceTypes.length > 0 ? { sourceTypes } : {}),
237
- ...(sourceSampleIds.length > 0 ? { sourceSampleIds } : {})
238
- });
239
- }
240
- export function mergeSessionCostTelemetry(base, next) {
241
- const patch = buildSessionCostTelemetry(next);
242
- const merged = {};
243
- const sessionId = patch.sessionId ?? base.sessionId;
244
- const provider = patch.provider ?? base.provider;
245
- const recordedAt = patch.recordedAt ?? base.recordedAt;
246
- const status = patch.status ?? base.status;
247
- const sourceSummary = mergeSourceSummary(base.sourceSummary, patch.sourceSummary);
248
- const durations = sumDurations(base.durations, patch.durations);
249
- const files = sumFiles(base.files, patch.files);
250
- const retries = sumRetries(base.retries, patch.retries);
251
- const capture = mergeCapture(base.capture, patch.capture);
252
- const providerUsage = [...(base.providerUsage ?? []), ...(patch.providerUsage ?? [])];
253
- const storage = sumStorage(base.storage, patch.storage);
254
- const proxy = sumProxy(base.proxy, patch.proxy);
255
- // Derived cost fields are LAST-WRITER-WINS (a re-derivation supersedes the
256
- // prior estimate), not summed — they are projections of the whole sample set,
257
- // not additive metrics.
258
- const billedCostUsd = patch.billedCostUsd ?? base.billedCostUsd;
259
- const costBasis = patch.costBasis ?? base.costBasis;
260
- // The settle-written half is DESCRIPTIVE of one settle (which basis, which
261
- // turn, which box, what the manifest counted), not additive across turns, so
262
- // it is last-writer-wins like the derived cost fields above. `childCostUsd` /
263
- // `childSessionCount` are already rollups over the whole child set.
264
- const basis = patch.basis ?? base.basis;
265
- const durationMs = patch.durationMs ?? base.durationMs;
266
- const turnSeq = patch.turnSeq ?? base.turnSeq;
267
- const runtimeSize = patch.runtimeSize ?? base.runtimeSize;
268
- const runtimeKind = patch.runtimeKind ?? base.runtimeKind;
269
- const model = patch.model ?? base.model;
270
- const usage = patch.usage ?? base.usage;
271
- const byteCounts = patch.byteCounts ?? base.byteCounts;
272
- const childCostUsd = patch.childCostUsd ?? base.childCostUsd;
273
- const childSessionCount = patch.childSessionCount ?? base.childSessionCount;
274
- const childProviderUsage = [...(base.childProviderUsage ?? []), ...(patch.childProviderUsage ?? [])];
275
- if (sessionId)
276
- merged.sessionId = sessionId;
277
- if (provider)
278
- merged.provider = provider;
279
- if (recordedAt)
280
- merged.recordedAt = recordedAt;
281
- if (status)
282
- merged.status = status;
283
- if (sourceSummary)
284
- merged.sourceSummary = sourceSummary;
285
- if (durations)
286
- merged.durations = durations;
287
- if (files)
288
- merged.files = files;
289
- if (retries)
290
- merged.retries = retries;
291
- if (capture)
292
- merged.capture = capture;
293
- if (providerUsage.length > 0)
294
- merged.providerUsage = providerUsage;
295
- if (storage)
296
- merged.storage = storage;
297
- if (proxy)
298
- merged.proxy = proxy;
299
- if (billedCostUsd !== undefined)
300
- merged.billedCostUsd = billedCostUsd;
301
- if (costBasis)
302
- merged.costBasis = costBasis;
303
- if (basis)
304
- merged.basis = basis;
305
- if (durationMs !== undefined)
306
- merged.durationMs = durationMs;
307
- if (turnSeq !== undefined)
308
- merged.turnSeq = turnSeq;
309
- if (runtimeSize)
310
- merged.runtimeSize = runtimeSize;
311
- if (runtimeKind)
312
- merged.runtimeKind = runtimeKind;
313
- if (model)
314
- merged.model = model;
315
- if (usage)
316
- merged.usage = usage;
317
- if (byteCounts)
318
- merged.byteCounts = byteCounts;
319
- if (childCostUsd !== undefined)
320
- merged.childCostUsd = childCostUsd;
321
- if (childSessionCount !== undefined)
322
- merged.childSessionCount = childSessionCount;
323
- if (childProviderUsage.length > 0)
324
- merged.childProviderUsage = childProviderUsage;
325
- return buildSessionCostTelemetry(merged);
326
- }
327
- function normalizeDurations(input) {
328
- return freezeOptionalNumbers({
329
- queuedMs: input.queuedMs,
330
- runtimeMs: input.runtimeMs,
331
- fileCaptureMs: input.fileCaptureMs,
332
- cleanupMs: input.cleanupMs,
333
- totalMs: input.totalMs
334
- });
335
- }
336
- function normalizeFiles(input) {
337
- return freezeOptionalNumbers({
338
- discoveredFiles: input.discoveredFiles,
339
- capturedFiles: input.capturedFiles,
340
- failedFiles: input.failedFiles,
341
- capturedBytes: input.capturedBytes
342
- });
343
- }
344
- function normalizeRetries(input) {
345
- return freezeOptionalNumbers({
346
- runtimeAttempts: input.runtimeAttempts,
347
- providerPollRetries: input.providerPollRetries,
348
- fileCaptureRetries: input.fileCaptureRetries,
349
- fileUploadRetries: input.fileUploadRetries
350
- });
351
- }
352
- function normalizeCapture(input) {
353
- return Object.freeze({
354
- attempted: input.attempted,
355
- ...freezeOptionalNumbers({
356
- uploadedFiles: input.uploadedFiles,
357
- failedFiles: input.failedFiles,
358
- totalBytes: input.totalBytes
359
- }),
360
- ...(input.failureReasons ? { failureReasons: Object.freeze([...input.failureReasons]) } : {})
361
- });
362
- }
363
- function normalizeProviderUsage(input) {
364
- return Object.freeze({
365
- provider: input.provider,
366
- ...(input.model ? { model: input.model } : {}),
367
- ...freezeOptionalNumbers({
368
- inputTokens: input.inputTokens,
369
- outputTokens: input.outputTokens,
370
- cacheReadInputTokens: input.cacheReadInputTokens,
371
- cacheCreationInputTokens: input.cacheCreationInputTokens,
372
- totalTokens: input.totalTokens
373
- }),
374
- ...(input.sourceEventId ? { sourceEventId: input.sourceEventId } : {}),
375
- ...(input.sourceSampleIds ? { sourceSampleIds: Object.freeze([...input.sourceSampleIds]) } : {})
376
- });
377
- }
378
- function normalizeStorage(input) {
379
- return freezeOptionalNumbers({
380
- storedBytes: input.storedBytes,
381
- storedFiles: input.storedFiles,
382
- byteMilliseconds: input.byteMilliseconds
383
- });
384
- }
385
- function normalizeProxy(input) {
386
- return freezeOptionalNumbers({
387
- calls: input.calls,
388
- failedCalls: input.failedCalls,
389
- requestBytes: input.requestBytes,
390
- responseBytes: input.responseBytes,
391
- durationMs: input.durationMs
392
- });
393
- }
394
- function normalizeSourceSummary(input) {
395
- return Object.freeze({
396
- sampleCount: nonNegativeFinite(input.sampleCount, "sourceSummary.sampleCount"),
397
- ...(input.metrics ? { metrics: Object.freeze(input.metrics.map(normalizeUsageSampleMetric)) } : {}),
398
- ...(input.sourceTypes
399
- ? { sourceTypes: Object.freeze(input.sourceTypes.map(normalizeUsageSampleSourceType)) }
400
- : {}),
401
- ...(input.sourceSampleIds
402
- ? { sourceSampleIds: Object.freeze(input.sourceSampleIds.map((id) => nonEmptyString(id, "sourceSampleIds"))) }
403
- : {})
404
- });
405
- }
406
- function normalizeUsageSampleSource(input) {
407
- if (!input || typeof input !== "object") {
408
- throw new Error("session usage sample source must be an object");
409
- }
410
- return Object.freeze({
411
- type: normalizeUsageSampleSourceType(input.type),
412
- id: nonEmptyString(input.id, "source.id"),
413
- ...(input.observedAt ? { observedAt: input.observedAt } : {})
414
- });
415
- }
416
- function normalizeUsageSampleMetric(input) {
417
- if (!isStringIn(input, SESSION_USAGE_SAMPLE_METRICS)) {
418
- throw new Error(`session usage sample metric ${String(input)} is not supported`);
419
- }
420
- return input;
421
- }
422
- function normalizeUsageSampleUnit(input) {
423
- if (!isStringIn(input, SESSION_USAGE_SAMPLE_UNITS)) {
424
- throw new Error(`session usage sample unit ${String(input)} is not supported`);
425
- }
426
- return input;
427
- }
428
- function normalizeUsageSampleSourceType(input) {
429
- if (!isStringIn(input, SESSION_USAGE_SAMPLE_SOURCE_TYPES)) {
430
- throw new Error(`session usage sample source type ${String(input)} is not supported`);
431
- }
432
- return input;
433
- }
434
- function normalizeSummaryStatus(input) {
435
- if (!isStringIn(input, SESSION_COST_SUMMARY_STATUSES)) {
436
- throw new Error(`session cost telemetry status ${String(input)} is not supported`);
437
- }
438
- return input;
439
- }
440
- function normalizeCostBasis(input) {
441
- if (!input || typeof input !== "object") {
442
- throw new Error("session cost basis must be an object");
443
- }
444
- if (input.currency !== "USD") {
445
- throw new Error(`session cost basis currency ${String(input.currency)} is not supported`);
446
- }
447
- if (!isStringIn(input.status, SESSION_COST_BASIS_STATUSES)) {
448
- throw new Error(`session cost basis status ${String(input.status)} is not supported`);
449
- }
450
- return Object.freeze({ currency: "USD", status: input.status });
451
- }
452
- function addProviderUsage(usageByKey, input, sample, field) {
453
- const provider = sample.provider ?? input.provider;
454
- if (!provider) {
455
- throw new Error(`session usage sample ${sample.metric} requires a provider`);
456
- }
457
- const key = `${provider}\u0000${sample.model ?? ""}`;
458
- const existing = usageByKey.get(key);
459
- const usage = existing ?? {
460
- provider,
461
- ...(sample.model ? { model: sample.model } : {}),
462
- sourceSampleIds: []
463
- };
464
- usage[field] = (usage[field] ?? 0) + sample.quantity;
465
- if (!usage.sourceEventId && (sample.source.type === "coordinator-event" || sample.source.type === "session-event")) {
466
- usage.sourceEventId = sample.source.id;
467
- }
468
- if (sample.sampleId) {
469
- usage.sourceSampleIds.push(sample.sampleId);
470
- }
471
- usageByKey.set(key, usage);
472
- }
473
- function publicProviderUsage(input) {
474
- return {
475
- provider: input.provider,
476
- ...(input.model ? { model: input.model } : {}),
477
- ...(input.inputTokens !== undefined ? { inputTokens: input.inputTokens } : {}),
478
- ...(input.outputTokens !== undefined ? { outputTokens: input.outputTokens } : {}),
479
- ...(input.cacheReadInputTokens !== undefined ? { cacheReadInputTokens: input.cacheReadInputTokens } : {}),
480
- ...(input.cacheCreationInputTokens !== undefined
481
- ? { cacheCreationInputTokens: input.cacheCreationInputTokens }
482
- : {}),
483
- ...(input.totalTokens !== undefined ? { totalTokens: input.totalTokens } : {}),
484
- ...(input.sourceEventId ? { sourceEventId: input.sourceEventId } : {}),
485
- ...(input.sourceSampleIds.length > 0 ? { sourceSampleIds: input.sourceSampleIds } : {})
486
- };
487
- }
488
- function addDraftNumber(target, key, quantity) {
489
- target[key] = (target[key] ?? 0) + quantity;
490
- }
491
- function freezeOptionalNumbers(input) {
492
- const out = {};
493
- for (const key of Object.keys(input)) {
494
- const value = input[key];
495
- if (value === undefined) {
496
- continue;
497
- }
498
- out[key] = nonNegativeFinite(value, key);
499
- }
500
- return Object.freeze(out);
501
- }
502
- function sumDurations(base, next) {
503
- return sumNumberFields(["queuedMs", "runtimeMs", "fileCaptureMs", "cleanupMs", "totalMs"], base, next);
504
- }
505
- function sumFiles(base, next) {
506
- return sumNumberFields(["discoveredFiles", "capturedFiles", "failedFiles", "capturedBytes"], base, next);
507
- }
508
- function sumRetries(base, next) {
509
- return sumNumberFields(["runtimeAttempts", "providerPollRetries", "fileCaptureRetries", "fileUploadRetries"], base, next);
510
- }
511
- function sumStorage(base, next) {
512
- return sumNumberFields(["storedBytes", "storedFiles", "byteMilliseconds"], base, next);
513
- }
514
- function sumProxy(base, next) {
515
- return sumNumberFields(["calls", "failedCalls", "requestBytes", "responseBytes", "durationMs"], base, next);
516
- }
517
- function sumNumberFields(keys, base, next) {
518
- if (!base && !next) {
519
- return undefined;
520
- }
521
- const out = {};
522
- for (const key of keys) {
523
- for (const source of [base, next]) {
524
- const value = source?.[key];
525
- if (value !== undefined) {
526
- out[key] = (out[key] ?? 0) + value;
527
- }
528
- }
529
- }
530
- return Object.keys(out).length > 0 ? Object.freeze(out) : undefined;
531
- }
532
- function mergeCapture(base, next) {
533
- if (!base && !next) {
534
- return undefined;
535
- }
536
- const failureReasons = [
537
- ...(base?.failureReasons ?? []),
538
- ...(next?.failureReasons ?? [])
539
- ];
540
- return normalizeCapture({
541
- attempted: Boolean(base?.attempted || next?.attempted),
542
- uploadedFiles: (base?.uploadedFiles ?? 0) + (next?.uploadedFiles ?? 0),
543
- failedFiles: (base?.failedFiles ?? 0) + (next?.failedFiles ?? 0),
544
- totalBytes: (base?.totalBytes ?? 0) + (next?.totalBytes ?? 0),
545
- ...(failureReasons.length > 0 ? { failureReasons } : {})
546
- });
547
- }
548
- function mergeSourceSummary(base, next) {
549
- if (!base && !next) {
550
- return undefined;
551
- }
552
- return normalizeSourceSummary({
553
- sampleCount: (base?.sampleCount ?? 0) + (next?.sampleCount ?? 0),
554
- metrics: unique([...(base?.metrics ?? []), ...(next?.metrics ?? [])]),
555
- sourceTypes: unique([...(base?.sourceTypes ?? []), ...(next?.sourceTypes ?? [])]),
556
- sourceSampleIds: unique([...(base?.sourceSampleIds ?? []), ...(next?.sourceSampleIds ?? [])])
557
- });
558
- }
559
- function freezeTelemetry(input) {
560
- return Object.freeze({
561
- ...input,
562
- ...(input.providerUsage ? { providerUsage: Object.freeze([...input.providerUsage]) } : {})
563
- });
564
- }
565
- function unique(input) {
566
- return Object.freeze([...new Set(input)]);
567
- }
568
- function nonEmptyString(value, field) {
569
- if (typeof value !== "string" || value.trim().length === 0) {
570
- throw new Error(`session cost telemetry ${field} must be a non-empty string`);
571
- }
572
- return value;
573
- }
574
- function nonNegativeFinite(value, field) {
575
- if (!Number.isFinite(value) || value < 0) {
576
- throw new Error(`session cost telemetry ${field} must be a non-negative finite number`);
577
- }
578
- return value;
579
- }
580
- function isStringIn(value, allowed) {
581
- return typeof value === "string" && allowed.includes(value);
582
- }