@lucern/sdk 1.0.1 → 1.0.2

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 (175) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/accessControl.d.ts +1 -0
  3. package/dist/accessControl.js +213 -26
  4. package/dist/accessControl.js.map +1 -1
  5. package/dist/adminClient.d.ts +1 -0
  6. package/dist/adminClient.js +213 -26
  7. package/dist/adminClient.js.map +1 -1
  8. package/dist/answersClient.d.ts +1 -0
  9. package/dist/answersClient.js +213 -26
  10. package/dist/answersClient.js.map +1 -1
  11. package/dist/audiencesClient.d.ts +1 -0
  12. package/dist/audiencesClient.js +213 -26
  13. package/dist/audiencesClient.js.map +1 -1
  14. package/dist/auditClient.d.ts +1 -0
  15. package/dist/auditClient.js +213 -26
  16. package/dist/auditClient.js.map +1 -1
  17. package/dist/authDeviceClient.d.ts +1 -0
  18. package/dist/beliefs/index.d.ts +1 -0
  19. package/dist/beliefs/index.js +214 -27
  20. package/dist/beliefs/index.js.map +1 -1
  21. package/dist/beliefsClient.d.ts +1 -0
  22. package/dist/beliefsClient.js +213 -26
  23. package/dist/beliefsClient.js.map +1 -1
  24. package/dist/client.d.ts +1 -0
  25. package/dist/client.js +214 -27
  26. package/dist/client.js.map +1 -1
  27. package/dist/clientConfig.d.ts +1 -0
  28. package/dist/clientEvidenceCompat.d.ts +1 -0
  29. package/dist/clientKnowledgeNamespaces.d.ts +1 -0
  30. package/dist/clientLocalHelpers.d.ts +1 -0
  31. package/dist/clientLocalHelpers.js +2 -0
  32. package/dist/clientLocalHelpers.js.map +1 -1
  33. package/dist/clientPlatformNamespaces.d.ts +1 -0
  34. package/dist/clientRuntime.d.ts +1 -0
  35. package/dist/clientWorkflowNamespaces.d.ts +1 -0
  36. package/dist/contextClient.d.ts +1 -0
  37. package/dist/contextClient.js +213 -26
  38. package/dist/contextClient.js.map +1 -1
  39. package/dist/contradictions/index.d.ts +1 -0
  40. package/dist/contradictions/index.js +214 -27
  41. package/dist/contradictions/index.js.map +1 -1
  42. package/dist/control-plane.d.ts +1 -0
  43. package/dist/control-plane.js +213 -26
  44. package/dist/control-plane.js.map +1 -1
  45. package/dist/coreClient.d.ts +25 -1
  46. package/dist/coreClient.js +217 -27
  47. package/dist/coreClient.js.map +1 -1
  48. package/dist/decisions/index.d.ts +1 -0
  49. package/dist/decisions/index.js +214 -27
  50. package/dist/decisions/index.js.map +1 -1
  51. package/dist/decisionsClient.d.ts +1 -0
  52. package/dist/decisionsClient.js +213 -26
  53. package/dist/decisionsClient.js.map +1 -1
  54. package/dist/edges/index.d.ts +1 -0
  55. package/dist/edges/index.js +214 -27
  56. package/dist/edges/index.js.map +1 -1
  57. package/dist/embeddingsClient.d.ts +1 -0
  58. package/dist/embeddingsClient.js +213 -26
  59. package/dist/embeddingsClient.js.map +1 -1
  60. package/dist/eventingClient.d.ts +1 -0
  61. package/dist/eventingClient.js +213 -26
  62. package/dist/eventingClient.js.map +1 -1
  63. package/dist/eventsCore.d.ts +1 -0
  64. package/dist/eventsCore.js +213 -26
  65. package/dist/eventsCore.js.map +1 -1
  66. package/dist/evidence/index.d.ts +1 -0
  67. package/dist/evidence/index.js +214 -27
  68. package/dist/evidence/index.js.map +1 -1
  69. package/dist/evidenceClient.d.ts +1 -0
  70. package/dist/evidenceClient.js +213 -26
  71. package/dist/evidenceClient.js.map +1 -1
  72. package/dist/functionSurface.d.ts +1 -0
  73. package/dist/functionSurface.js +213 -26
  74. package/dist/functionSurface.js.map +1 -1
  75. package/dist/functionSurfaceClient.d.ts +1 -0
  76. package/dist/functionSurfaceClient.js +213 -26
  77. package/dist/functionSurfaceClient.js.map +1 -1
  78. package/dist/gatewayFacades.d.ts +1 -0
  79. package/dist/gatewayFacades.factories.d.ts +1 -0
  80. package/dist/gatewayFacades.factories.js +213 -26
  81. package/dist/gatewayFacades.factories.js.map +1 -1
  82. package/dist/gatewayFacades.js +213 -26
  83. package/dist/gatewayFacades.js.map +1 -1
  84. package/dist/graphAnalysisClient.d.ts +1 -0
  85. package/dist/graphAnalysisClient.js +213 -26
  86. package/dist/graphAnalysisClient.js.map +1 -1
  87. package/dist/graphClient.d.ts +1 -0
  88. package/dist/graphClient.js +213 -26
  89. package/dist/graphClient.js.map +1 -1
  90. package/dist/graphRecommendationsClient.d.ts +1 -0
  91. package/dist/graphRecommendationsClient.js +213 -26
  92. package/dist/graphRecommendationsClient.js.map +1 -1
  93. package/dist/graphStateClassifierClient.d.ts +1 -0
  94. package/dist/graphStateClassifierClient.js +213 -26
  95. package/dist/graphStateClassifierClient.js.map +1 -1
  96. package/dist/harnessClient.d.ts +1 -0
  97. package/dist/harnessClient.js +213 -26
  98. package/dist/harnessClient.js.map +1 -1
  99. package/dist/identityClient.d.ts +1 -0
  100. package/dist/identityClient.js +213 -26
  101. package/dist/identityClient.js.map +1 -1
  102. package/dist/index.d.ts +2 -1
  103. package/dist/index.js +237 -28
  104. package/dist/index.js.map +1 -1
  105. package/dist/jobsClient.d.ts +1 -0
  106. package/dist/jobsClient.js +213 -26
  107. package/dist/jobsClient.js.map +1 -1
  108. package/dist/learningClient.d.ts +1 -0
  109. package/dist/learningClient.js +213 -26
  110. package/dist/learningClient.js.map +1 -1
  111. package/dist/lenses/index.d.ts +1 -0
  112. package/dist/lenses/index.js +214 -27
  113. package/dist/lenses/index.js.map +1 -1
  114. package/dist/mcpClient.d.ts +1 -0
  115. package/dist/mcpClient.js +213 -26
  116. package/dist/mcpClient.js.map +1 -1
  117. package/dist/modelRuntimeClient.d.ts +1 -0
  118. package/dist/modelRuntimeClient.js +213 -26
  119. package/dist/modelRuntimeClient.js.map +1 -1
  120. package/dist/nodes/index.d.ts +1 -0
  121. package/dist/nodes/index.js +214 -27
  122. package/dist/nodes/index.js.map +1 -1
  123. package/dist/ontologies/index.d.ts +1 -0
  124. package/dist/ontologies/index.js +214 -27
  125. package/dist/ontologies/index.js.map +1 -1
  126. package/dist/ontologyClient.d.ts +1 -0
  127. package/dist/ontologyClient.js +213 -26
  128. package/dist/ontologyClient.js.map +1 -1
  129. package/dist/ontologyLinksClient.d.ts +1 -0
  130. package/dist/ontologyLinksClient.js +213 -26
  131. package/dist/ontologyLinksClient.js.map +1 -1
  132. package/dist/orgGraphSearchClient.d.ts +1 -0
  133. package/dist/orgGraphSearchClient.js +213 -26
  134. package/dist/orgGraphSearchClient.js.map +1 -1
  135. package/dist/packsClient.d.ts +1 -0
  136. package/dist/packsClient.js +213 -26
  137. package/dist/packsClient.js.map +1 -1
  138. package/dist/policyClient.d.ts +1 -0
  139. package/dist/policyClient.js +213 -26
  140. package/dist/policyClient.js.map +1 -1
  141. package/dist/questions/index.d.ts +1 -0
  142. package/dist/questions/index.js +214 -27
  143. package/dist/questions/index.js.map +1 -1
  144. package/dist/reportsClient.d.ts +1 -0
  145. package/dist/reportsClient.js +213 -26
  146. package/dist/reportsClient.js.map +1 -1
  147. package/dist/schemaClient.d.ts +1 -0
  148. package/dist/schemaClient.js +213 -26
  149. package/dist/schemaClient.js.map +1 -1
  150. package/dist/sdkSurface.d.ts +1 -0
  151. package/dist/sourcesClient.d.ts +1 -0
  152. package/dist/sourcesClient.js +213 -26
  153. package/dist/sourcesClient.js.map +1 -1
  154. package/dist/telemetryClient.d.ts +1 -0
  155. package/dist/telemetryClient.js +213 -26
  156. package/dist/telemetryClient.js.map +1 -1
  157. package/dist/toolRegistryClient.d.ts +1 -0
  158. package/dist/toolRegistryClient.js +213 -26
  159. package/dist/toolRegistryClient.js.map +1 -1
  160. package/dist/topics/index.d.ts +1 -0
  161. package/dist/topics/index.js +214 -27
  162. package/dist/topics/index.js.map +1 -1
  163. package/dist/topicsClient.d.ts +1 -0
  164. package/dist/topicsClient.js +213 -26
  165. package/dist/topicsClient.js.map +1 -1
  166. package/dist/version.d.ts +1 -1
  167. package/dist/version.js +1 -1
  168. package/dist/version.js.map +1 -1
  169. package/dist/workflowClient.d.ts +1 -0
  170. package/dist/workflowClient.js +213 -26
  171. package/dist/workflowClient.js.map +1 -1
  172. package/dist/worktrees/index.d.ts +1 -0
  173. package/dist/worktrees/index.js +214 -27
  174. package/dist/worktrees/index.js.map +1 -1
  175. package/package.json +6 -5
package/CHANGELOG.md CHANGED
@@ -5,6 +5,10 @@ All notable changes to `@lucern/sdk` will be documented in this file.
5
5
  ## [Unreleased]
6
6
  - No unreleased changes yet.
7
7
 
8
+ ## [1.0.2] - 2026-05-27
9
+ - Campaign 1 wrap-up release with expanded CLI targeting and observability pilot surfaces.
10
+
11
+
8
12
  ## [1.0.1] - 2026-05-26
9
13
  - Publish the Campaign 1 runtime lifecycle, graph-native CLI, Effect runtime,
10
14
  XState lifecycle, and transport-core package line as a coherent patch release.
@@ -3,6 +3,7 @@ import { GatewayClientConfig } from './coreClient.js';
3
3
  import { PolicyEvaluationInput, PolicyDecisionRecord } from './identityClient.js';
4
4
  import { SessionPrincipalType } from './contracts/auth-session.contract.js';
5
5
  import { JsonObject } from './types.js';
6
+ import '@lucern/transport-core';
6
7
  import './control-plane.js';
7
8
  import './contracts/workflow-runtime.contract.js';
8
9
  import './contracts/lens-workflow.contract.js';
@@ -1,5 +1,7 @@
1
+ import { createTelemetryExporterFromEnv, emitTelemetrySignal } from '@lucern/transport-core';
1
2
  import { redactDiagnosticValue } from '@lucern/transport-core/redaction';
2
3
  import { classifyRetry } from '@lucern/transport-core/transport';
4
+ import { Effect, Exit, Cause } from 'effect';
3
5
 
4
6
  // src/authContext.ts
5
7
  var LucernSdkAuthContextError = class extends Error {
@@ -167,6 +169,33 @@ function createCanonicalAuthHeaders(authContext) {
167
169
  }
168
170
  return headers;
169
171
  }
172
+ var DEFAULT_GATEWAY_TIMEOUT_MS = 15e3;
173
+ var DEFAULT_GATEWAY_MAX_RETRIES = 2;
174
+ var DEFAULT_ENV_TIMEOUT_MS = "LUCERN_REQUEST_TIMEOUT_MS";
175
+ var DEFAULT_ENV_MAX_RETRIES = "LUCERN_GATEWAY_MAX_RETRIES";
176
+ var ENV_TIMEOUT_BY_METHOD_PREFIX = "LUCERN_REQUEST_TIMEOUT_MS_";
177
+ var GatewayTimeoutError = class extends Error {
178
+ retryable = true;
179
+ timeoutMs;
180
+ constructor(timeoutMs) {
181
+ super(`Request timed out after ${timeoutMs}ms`);
182
+ this.name = "AbortError";
183
+ this.timeoutMs = timeoutMs;
184
+ }
185
+ };
186
+ var GatewayTransportError = class extends Error {
187
+ retryable;
188
+ cause;
189
+ constructor(message, options) {
190
+ super(message);
191
+ this.name = "GatewayTransportError";
192
+ this.retryable = options?.retryable ?? true;
193
+ this.cause = options?.cause;
194
+ }
195
+ };
196
+ function isGatewayRetryableError(error) {
197
+ return error instanceof GatewayTimeoutError && error.retryable || error instanceof GatewayTransportError && error.retryable || false;
198
+ }
170
199
  var LucernApiError = class extends Error {
171
200
  code;
172
201
  status;
@@ -233,6 +262,99 @@ function generatePortableRequestId() {
233
262
  8
234
263
  ).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
235
264
  }
265
+ function resolveEnvironment() {
266
+ const processEnv = typeof globalThis === "object" && globalThis !== null && "process" in globalThis ? globalThis.process : void 0;
267
+ const env = processEnv !== void 0 && typeof processEnv === "object" && processEnv !== null && typeof processEnv.env === "object" ? processEnv.env : void 0;
268
+ return {
269
+ get: (name) => {
270
+ const value = env?.[name];
271
+ return typeof value === "string" && value.length > 0 ? value : void 0;
272
+ }
273
+ };
274
+ }
275
+ function telemetryEnvironmentRecord(environment) {
276
+ const names = [
277
+ "LUCERN_TELEMETRY_ENABLED",
278
+ "AXIOM_TELEMETRY_ENABLED",
279
+ "LUCERN_AXIOM_TOKEN",
280
+ "AXIOM_TOKEN",
281
+ "LUCERN_AXIOM_EVENTS_DATASET",
282
+ "LUCERN_AXIOM_DATASET",
283
+ "AXIOM_EVENTS_DATASET",
284
+ "AXIOM_DATASET",
285
+ "LUCERN_AXIOM_API_URL",
286
+ "AXIOM_URL",
287
+ "LUCERN_ENVIRONMENT",
288
+ "NODE_ENV",
289
+ "LUCERN_RELEASE",
290
+ "SENTRY_RELEASE",
291
+ "VERCEL_GIT_COMMIT_SHA"
292
+ ];
293
+ return Object.fromEntries(
294
+ names.map((name) => [name, environment.get(name)])
295
+ );
296
+ }
297
+ function resolveRequestProfile(config, environment) {
298
+ const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
299
+ const parsedMaxRetries = parseIntegerFromString(
300
+ config.maxRetries,
301
+ environment.get(DEFAULT_ENV_MAX_RETRIES)
302
+ );
303
+ const parsedTimeoutMs = parseIntegerFromString(
304
+ config.timeoutMs,
305
+ environment.get(DEFAULT_ENV_TIMEOUT_MS)
306
+ );
307
+ const methodTimeouts = {
308
+ ...config.timeoutMsByMethod
309
+ };
310
+ for (const method of ["GET", "POST", "PUT", "PATCH", "DELETE"]) {
311
+ const envKey = `${ENV_TIMEOUT_BY_METHOD_PREFIX}${method}`;
312
+ const raw = environment.get(envKey);
313
+ if (!raw || methodTimeouts[method] !== void 0) {
314
+ continue;
315
+ }
316
+ const parsed = parseIntegerFromString(void 0, raw);
317
+ if (typeof parsed === "number") {
318
+ methodTimeouts[method] = parsed;
319
+ }
320
+ }
321
+ return {
322
+ maxRetries: parsedMaxRetries ?? DEFAULT_GATEWAY_MAX_RETRIES,
323
+ timeoutMs: parsedTimeoutMs ?? DEFAULT_GATEWAY_TIMEOUT_MS,
324
+ timeoutMsByMethod: methodTimeouts,
325
+ requestIdFactory
326
+ };
327
+ }
328
+ function createGatewayRuntime(config, environment) {
329
+ return {
330
+ fetch: config.fetchImpl ?? fetch,
331
+ now: () => Date.now(),
332
+ sleep: (ms) => delay(ms),
333
+ env: environment,
334
+ redaction: resolveRequestRedactionValue,
335
+ profile: resolveRequestProfile(config, environment)
336
+ };
337
+ }
338
+ function parseIntegerFromString(value, rawValue) {
339
+ if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
340
+ return value;
341
+ }
342
+ if (typeof rawValue !== "string" || !rawValue.trim()) {
343
+ return void 0;
344
+ }
345
+ const parsed = Number.parseInt(rawValue, 10);
346
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
347
+ }
348
+ function resolveRequestRedactionValue(value) {
349
+ return redactDiagnosticValue(value);
350
+ }
351
+ function resolveGatewayBaseUrl(configBaseUrl, environment) {
352
+ const envBaseUrl = environment.get("LUCERN_API_URL") ?? environment.get("LUCERN_BASE_URL") ?? environment.get("LUCERN_GATEWAY_BASE_URL");
353
+ return (configBaseUrl ?? envBaseUrl ?? "").replace(/\/+$/, "");
354
+ }
355
+ function normalizeGatewayEnvironment(value) {
356
+ return value === "sandbox" || value === "production" ? value : void 0;
357
+ }
236
358
  var randomIdempotencyKey = generatePortableRequestId;
237
359
  function fallbackErrorCode(status) {
238
360
  if (status === 401) {
@@ -272,10 +394,8 @@ function computeRetryDelayMs(args) {
272
394
  const jitterWindow = Math.max(250, Math.round(baseDelay * 0.25));
273
395
  return baseDelay + Math.round(Math.random() * jitterWindow);
274
396
  }
275
- function timeoutError(timeoutMs) {
276
- const error = new Error(`Request timed out after ${timeoutMs}ms`);
277
- error.name = "AbortError";
278
- return error;
397
+ function classifyGatewayErrorForRetry(error) {
398
+ return isGatewayRetryableError(error) || classifyRetry({ error }).retryable;
279
399
  }
280
400
  function isRecord(value) {
281
401
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -330,10 +450,18 @@ function cleanHeaderValue(value) {
330
450
  return normalized ? normalized : void 0;
331
451
  }
332
452
  function createGatewayRequestClient(config = {}) {
333
- const fetchImpl = config.fetchImpl ?? fetch;
334
- const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
335
- const maxRetries = config.maxRetries ?? 2;
336
- const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
453
+ const env = resolveEnvironment();
454
+ const runtime = createGatewayRuntime(config, env);
455
+ const baseUrl = resolveGatewayBaseUrl(config.baseUrl, env);
456
+ const maxRetries = runtime.profile.maxRetries;
457
+ const requestIdFactory = runtime.profile.requestIdFactory;
458
+ const requestTimeoutByMethod = runtime.profile.timeoutMsByMethod;
459
+ const defaultRequestTimeoutMs = runtime.profile.timeoutMs;
460
+ const normalizedEnvironment = normalizeGatewayEnvironment(config.environment);
461
+ const telemetryExporter = config.telemetryEnabled === false ? null : config.telemetryExporter ?? createTelemetryExporterFromEnv(telemetryEnvironmentRecord(env), {
462
+ service: "lucern-sdk",
463
+ environment: normalizedEnvironment
464
+ });
337
465
  async function resolveAuthHeaders() {
338
466
  const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
339
467
  const headers = new Headers(provided);
@@ -345,7 +473,7 @@ function createGatewayRequestClient(config = {}) {
345
473
  };
346
474
  setIfAbsent("x-lucern-key", config.apiKey);
347
475
  setIfAbsent("x-lucern-session-token", config.userToken);
348
- setIfAbsent("x-lucern-environment", config.environment);
476
+ setIfAbsent("x-lucern-environment", normalizedEnvironment);
349
477
  setIfAbsent("x-lucern-clerk-id", config.clerkId);
350
478
  setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
351
479
  setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
@@ -360,19 +488,73 @@ function createGatewayRequestClient(config = {}) {
360
488
  return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
361
489
  }
362
490
  async function fetchWithTimeout(url, init, timeoutMs) {
491
+ const normalizeTransportError = (error, isTimeout) => {
492
+ if (isTimeout) {
493
+ return new GatewayTimeoutError(timeoutMs);
494
+ }
495
+ return error instanceof GatewayTimeoutError || error instanceof GatewayTransportError ? error : new GatewayTransportError(
496
+ error instanceof Error ? error.message : "Gateway transport error",
497
+ {
498
+ cause: error,
499
+ retryable: classifyGatewayErrorForRetry(error)
500
+ }
501
+ );
502
+ };
363
503
  const controller = new AbortController();
364
504
  const timer = setTimeout(() => controller.abort(), timeoutMs);
505
+ const requestEffect = Effect.tryPromise({
506
+ try: () => runtime.fetch(url, { ...init, signal: controller.signal }),
507
+ catch: (error) => normalizeTransportError(error, controller.signal.aborted)
508
+ });
365
509
  try {
366
- return await fetchImpl(url, { ...init, signal: controller.signal });
367
- } catch (error) {
368
- if (controller.signal.aborted) {
369
- throw timeoutError(timeoutMs);
510
+ const exit = await Effect.runPromiseExit(requestEffect);
511
+ if (Exit.isSuccess(exit)) {
512
+ return exit.value;
370
513
  }
371
- throw error;
514
+ const failure = Array.from(Cause.failures(exit.cause))[0];
515
+ if (failure !== void 0) {
516
+ throw failure;
517
+ }
518
+ throw Cause.squash(exit.cause);
372
519
  } finally {
373
520
  clearTimeout(timer);
374
521
  }
375
522
  }
523
+ async function emitSdkResponseTelemetry(context) {
524
+ const retry = classifyRetry({
525
+ status: context.status,
526
+ error: context.error,
527
+ retryAfter: context.retryAfterMs !== null && context.retryAfterMs !== void 0 ? String(context.retryAfterMs / 1e3) : void 0
528
+ });
529
+ await emitTelemetrySignal(telemetryExporter, {
530
+ signalType: "trace",
531
+ surface: "sdk-retry",
532
+ eventName: context.willRetry ? "sdk.retry" : context.error ? "sdk.request.error" : "sdk.request.complete",
533
+ severity: context.error ? context.willRetry ? "warn" : "error" : "info",
534
+ durationMs: context.durationMs,
535
+ metricName: "sdk.request.duration_ms",
536
+ metricValue: context.durationMs,
537
+ correlationId: context.correlationId ?? context.requestId,
538
+ policyTraceId: context.policyTraceId ?? null,
539
+ tenantId: context.headers.get("x-lucern-tenant-id") ?? context.headers.get("x-lucern-tenant") ?? void 0,
540
+ workspaceId: context.headers.get("x-lucern-workspace-id") ?? context.headers.get("x-lucern-workspace") ?? void 0,
541
+ attributes: {
542
+ service: "lucern-sdk",
543
+ operation: "gateway.request",
544
+ path: context.path,
545
+ httpMethod: context.method,
546
+ httpStatus: context.status,
547
+ attempt: context.attempt,
548
+ maxRetries: context.maxRetries,
549
+ retryReason: retry.reason,
550
+ retryAfterMs: context.retryAfterMs ?? retry.retryAfterMs,
551
+ willRetry: context.willRetry,
552
+ retryable: retry.retryable,
553
+ errorName: context.error instanceof Error ? context.error.name : void 0,
554
+ errorMessage: context.error instanceof Error ? context.error.message : void 0
555
+ }
556
+ });
557
+ }
376
558
  async function parsePayload(response) {
377
559
  const text = await response.text();
378
560
  if (!text) {
@@ -388,11 +570,11 @@ function createGatewayRequestClient(config = {}) {
388
570
  if (typeof requestTimeoutMs === "number") {
389
571
  return requestTimeoutMs;
390
572
  }
391
- const methodTimeoutMs = config.timeoutMsByMethod?.[method];
573
+ const methodTimeoutMs = requestTimeoutByMethod?.[method];
392
574
  if (typeof methodTimeoutMs === "number") {
393
575
  return methodTimeoutMs;
394
576
  }
395
- return config.timeoutMs ?? 15e3;
577
+ return defaultRequestTimeoutMs;
396
578
  }
397
579
  function tryParseGatewayEnvelopeJson(text) {
398
580
  const trimmed = text.trim();
@@ -413,8 +595,8 @@ function createGatewayRequestClient(config = {}) {
413
595
  const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
414
596
  const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
415
597
  const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
416
- const details = redactJsonDiagnosticValue(
417
- failure?.details ?? legacyError?.details
598
+ const details = runtime.redaction(
599
+ redactJsonDiagnosticValue(failure?.details ?? legacyError?.details)
418
600
  );
419
601
  const policySummary = readPolicySummaryFromDetails(details);
420
602
  const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
@@ -484,7 +666,7 @@ function createGatewayRequestClient(config = {}) {
484
666
  failure
485
667
  });
486
668
  const willRetry = attempt < maxRetries && retry.retryable;
487
- await config.onResponse?.({
669
+ const responseContext2 = {
488
670
  ...hookRequestContext,
489
671
  durationMs: Date.now() - startedAt,
490
672
  status: response.status,
@@ -494,7 +676,9 @@ function createGatewayRequestClient(config = {}) {
494
676
  policyTraceId: apiError.policyTraceId ?? null,
495
677
  retryAfterMs,
496
678
  willRetry
497
- });
679
+ };
680
+ await config.onResponse?.(responseContext2);
681
+ await emitSdkResponseTelemetry(responseContext2);
498
682
  if (willRetry) {
499
683
  lastError = apiError;
500
684
  await delay(
@@ -509,7 +693,7 @@ function createGatewayRequestClient(config = {}) {
509
693
  throw apiError;
510
694
  }
511
695
  const successPayload = payload;
512
- await config.onResponse?.({
696
+ const responseContext = {
513
697
  ...hookRequestContext,
514
698
  durationMs: Date.now() - startedAt,
515
699
  status: response.status,
@@ -519,22 +703,25 @@ function createGatewayRequestClient(config = {}) {
519
703
  idempotentReplay: successPayload.idempotentReplay,
520
704
  retryAfterMs,
521
705
  willRetry: false
522
- });
706
+ };
707
+ await config.onResponse?.(responseContext);
708
+ await emitSdkResponseTelemetry(responseContext);
523
709
  return successPayload;
524
710
  } catch (fetchError) {
525
711
  if (fetchError instanceof LucernApiError) {
526
712
  throw fetchError;
527
713
  }
528
- const retry = classifyRetry({ error: fetchError });
529
- const willRetry = attempt < maxRetries && retry.retryable;
530
- await config.onResponse?.({
714
+ const willRetry = attempt < maxRetries && classifyGatewayErrorForRetry(fetchError);
715
+ const responseContext = {
531
716
  ...hookRequestContext,
532
717
  durationMs: Date.now() - startedAt,
533
718
  error: fetchError,
534
719
  correlationId: requestId,
535
720
  policyTraceId: null,
536
721
  willRetry
537
- });
722
+ };
723
+ await config.onResponse?.(responseContext);
724
+ await emitSdkResponseTelemetry(responseContext);
538
725
  lastError = fetchError;
539
726
  if (willRetry) {
540
727
  await delay(computeRetryDelayMs({ attempt }));