@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/dist/client.js CHANGED
@@ -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
  import { z } from 'zod';
4
6
  import { MCP_GATEWAY_EVALUATE_RESEARCH_CONTRACT_ENDPOINT, MCP_GATEWAY_EVALUATE_ENGINEERING_CONTRACT_ENDPOINT, MCP_GATEWAY_BEGIN_BUILD_SESSION_ENDPOINT, MCP_GATEWAY_WRITE_POLICY_CHECK_ENDPOINT, MCP_GATEWAY_BOOTSTRAP_ENDPOINT } from '@lucern/contracts/mcp-gateway-boundary.contract';
5
7
 
@@ -173,6 +175,33 @@ function createCanonicalAuthHeaders(authContext) {
173
175
  }
174
176
 
175
177
  // src/coreClient.ts
178
+ var DEFAULT_GATEWAY_TIMEOUT_MS = 15e3;
179
+ var DEFAULT_GATEWAY_MAX_RETRIES = 2;
180
+ var DEFAULT_ENV_TIMEOUT_MS = "LUCERN_REQUEST_TIMEOUT_MS";
181
+ var DEFAULT_ENV_MAX_RETRIES = "LUCERN_GATEWAY_MAX_RETRIES";
182
+ var ENV_TIMEOUT_BY_METHOD_PREFIX = "LUCERN_REQUEST_TIMEOUT_MS_";
183
+ var GatewayTimeoutError = class extends Error {
184
+ retryable = true;
185
+ timeoutMs;
186
+ constructor(timeoutMs) {
187
+ super(`Request timed out after ${timeoutMs}ms`);
188
+ this.name = "AbortError";
189
+ this.timeoutMs = timeoutMs;
190
+ }
191
+ };
192
+ var GatewayTransportError = class extends Error {
193
+ retryable;
194
+ cause;
195
+ constructor(message, options) {
196
+ super(message);
197
+ this.name = "GatewayTransportError";
198
+ this.retryable = options?.retryable ?? true;
199
+ this.cause = options?.cause;
200
+ }
201
+ };
202
+ function isGatewayRetryableError(error) {
203
+ return error instanceof GatewayTimeoutError && error.retryable || error instanceof GatewayTransportError && error.retryable || false;
204
+ }
176
205
  var LucernApiError = class extends Error {
177
206
  code;
178
207
  status;
@@ -239,6 +268,99 @@ function generatePortableRequestId() {
239
268
  8
240
269
  ).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
241
270
  }
271
+ function resolveEnvironment() {
272
+ const processEnv = typeof globalThis === "object" && globalThis !== null && "process" in globalThis ? globalThis.process : void 0;
273
+ const env = processEnv !== void 0 && typeof processEnv === "object" && processEnv !== null && typeof processEnv.env === "object" ? processEnv.env : void 0;
274
+ return {
275
+ get: (name) => {
276
+ const value = env?.[name];
277
+ return typeof value === "string" && value.length > 0 ? value : void 0;
278
+ }
279
+ };
280
+ }
281
+ function telemetryEnvironmentRecord(environment) {
282
+ const names = [
283
+ "LUCERN_TELEMETRY_ENABLED",
284
+ "AXIOM_TELEMETRY_ENABLED",
285
+ "LUCERN_AXIOM_TOKEN",
286
+ "AXIOM_TOKEN",
287
+ "LUCERN_AXIOM_EVENTS_DATASET",
288
+ "LUCERN_AXIOM_DATASET",
289
+ "AXIOM_EVENTS_DATASET",
290
+ "AXIOM_DATASET",
291
+ "LUCERN_AXIOM_API_URL",
292
+ "AXIOM_URL",
293
+ "LUCERN_ENVIRONMENT",
294
+ "NODE_ENV",
295
+ "LUCERN_RELEASE",
296
+ "SENTRY_RELEASE",
297
+ "VERCEL_GIT_COMMIT_SHA"
298
+ ];
299
+ return Object.fromEntries(
300
+ names.map((name) => [name, environment.get(name)])
301
+ );
302
+ }
303
+ function resolveRequestProfile(config, environment) {
304
+ const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
305
+ const parsedMaxRetries = parseIntegerFromString(
306
+ config.maxRetries,
307
+ environment.get(DEFAULT_ENV_MAX_RETRIES)
308
+ );
309
+ const parsedTimeoutMs = parseIntegerFromString(
310
+ config.timeoutMs,
311
+ environment.get(DEFAULT_ENV_TIMEOUT_MS)
312
+ );
313
+ const methodTimeouts = {
314
+ ...config.timeoutMsByMethod
315
+ };
316
+ for (const method of ["GET", "POST", "PUT", "PATCH", "DELETE"]) {
317
+ const envKey = `${ENV_TIMEOUT_BY_METHOD_PREFIX}${method}`;
318
+ const raw = environment.get(envKey);
319
+ if (!raw || methodTimeouts[method] !== void 0) {
320
+ continue;
321
+ }
322
+ const parsed = parseIntegerFromString(void 0, raw);
323
+ if (typeof parsed === "number") {
324
+ methodTimeouts[method] = parsed;
325
+ }
326
+ }
327
+ return {
328
+ maxRetries: parsedMaxRetries ?? DEFAULT_GATEWAY_MAX_RETRIES,
329
+ timeoutMs: parsedTimeoutMs ?? DEFAULT_GATEWAY_TIMEOUT_MS,
330
+ timeoutMsByMethod: methodTimeouts,
331
+ requestIdFactory
332
+ };
333
+ }
334
+ function createGatewayRuntime(config, environment) {
335
+ return {
336
+ fetch: config.fetchImpl ?? fetch,
337
+ now: () => Date.now(),
338
+ sleep: (ms) => delay(ms),
339
+ env: environment,
340
+ redaction: resolveRequestRedactionValue,
341
+ profile: resolveRequestProfile(config, environment)
342
+ };
343
+ }
344
+ function parseIntegerFromString(value, rawValue) {
345
+ if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
346
+ return value;
347
+ }
348
+ if (typeof rawValue !== "string" || !rawValue.trim()) {
349
+ return void 0;
350
+ }
351
+ const parsed = Number.parseInt(rawValue, 10);
352
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
353
+ }
354
+ function resolveRequestRedactionValue(value) {
355
+ return redactDiagnosticValue(value);
356
+ }
357
+ function resolveGatewayBaseUrl(configBaseUrl, environment) {
358
+ const envBaseUrl = environment.get("LUCERN_API_URL") ?? environment.get("LUCERN_BASE_URL") ?? environment.get("LUCERN_GATEWAY_BASE_URL");
359
+ return (configBaseUrl ?? envBaseUrl ?? "").replace(/\/+$/, "");
360
+ }
361
+ function normalizeGatewayEnvironment(value) {
362
+ return value === "sandbox" || value === "production" ? value : void 0;
363
+ }
242
364
  var randomIdempotencyKey = generatePortableRequestId;
243
365
  function fallbackErrorCode(status) {
244
366
  if (status === 401) {
@@ -278,10 +400,8 @@ function computeRetryDelayMs(args) {
278
400
  const jitterWindow = Math.max(250, Math.round(baseDelay * 0.25));
279
401
  return baseDelay + Math.round(Math.random() * jitterWindow);
280
402
  }
281
- function timeoutError(timeoutMs) {
282
- const error = new Error(`Request timed out after ${timeoutMs}ms`);
283
- error.name = "AbortError";
284
- return error;
403
+ function classifyGatewayErrorForRetry(error) {
404
+ return isGatewayRetryableError(error) || classifyRetry({ error }).retryable;
285
405
  }
286
406
  function isRecord(value) {
287
407
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -336,10 +456,18 @@ function cleanHeaderValue(value) {
336
456
  return normalized ? normalized : void 0;
337
457
  }
338
458
  function createGatewayRequestClient(config = {}) {
339
- const fetchImpl = config.fetchImpl ?? fetch;
340
- const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
341
- const maxRetries = config.maxRetries ?? 2;
342
- const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
459
+ const env = resolveEnvironment();
460
+ const runtime = createGatewayRuntime(config, env);
461
+ const baseUrl = resolveGatewayBaseUrl(config.baseUrl, env);
462
+ const maxRetries = runtime.profile.maxRetries;
463
+ const requestIdFactory = runtime.profile.requestIdFactory;
464
+ const requestTimeoutByMethod = runtime.profile.timeoutMsByMethod;
465
+ const defaultRequestTimeoutMs = runtime.profile.timeoutMs;
466
+ const normalizedEnvironment = normalizeGatewayEnvironment(config.environment);
467
+ const telemetryExporter = config.telemetryEnabled === false ? null : config.telemetryExporter ?? createTelemetryExporterFromEnv(telemetryEnvironmentRecord(env), {
468
+ service: "lucern-sdk",
469
+ environment: normalizedEnvironment
470
+ });
343
471
  async function resolveAuthHeaders() {
344
472
  const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
345
473
  const headers = new Headers(provided);
@@ -351,7 +479,7 @@ function createGatewayRequestClient(config = {}) {
351
479
  };
352
480
  setIfAbsent("x-lucern-key", config.apiKey);
353
481
  setIfAbsent("x-lucern-session-token", config.userToken);
354
- setIfAbsent("x-lucern-environment", config.environment);
482
+ setIfAbsent("x-lucern-environment", normalizedEnvironment);
355
483
  setIfAbsent("x-lucern-clerk-id", config.clerkId);
356
484
  setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
357
485
  setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
@@ -366,19 +494,73 @@ function createGatewayRequestClient(config = {}) {
366
494
  return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
367
495
  }
368
496
  async function fetchWithTimeout(url, init, timeoutMs) {
497
+ const normalizeTransportError = (error, isTimeout) => {
498
+ if (isTimeout) {
499
+ return new GatewayTimeoutError(timeoutMs);
500
+ }
501
+ return error instanceof GatewayTimeoutError || error instanceof GatewayTransportError ? error : new GatewayTransportError(
502
+ error instanceof Error ? error.message : "Gateway transport error",
503
+ {
504
+ cause: error,
505
+ retryable: classifyGatewayErrorForRetry(error)
506
+ }
507
+ );
508
+ };
369
509
  const controller = new AbortController();
370
510
  const timer = setTimeout(() => controller.abort(), timeoutMs);
511
+ const requestEffect = Effect.tryPromise({
512
+ try: () => runtime.fetch(url, { ...init, signal: controller.signal }),
513
+ catch: (error) => normalizeTransportError(error, controller.signal.aborted)
514
+ });
371
515
  try {
372
- return await fetchImpl(url, { ...init, signal: controller.signal });
373
- } catch (error) {
374
- if (controller.signal.aborted) {
375
- throw timeoutError(timeoutMs);
516
+ const exit = await Effect.runPromiseExit(requestEffect);
517
+ if (Exit.isSuccess(exit)) {
518
+ return exit.value;
376
519
  }
377
- throw error;
520
+ const failure = Array.from(Cause.failures(exit.cause))[0];
521
+ if (failure !== void 0) {
522
+ throw failure;
523
+ }
524
+ throw Cause.squash(exit.cause);
378
525
  } finally {
379
526
  clearTimeout(timer);
380
527
  }
381
528
  }
529
+ async function emitSdkResponseTelemetry(context) {
530
+ const retry = classifyRetry({
531
+ status: context.status,
532
+ error: context.error,
533
+ retryAfter: context.retryAfterMs !== null && context.retryAfterMs !== void 0 ? String(context.retryAfterMs / 1e3) : void 0
534
+ });
535
+ await emitTelemetrySignal(telemetryExporter, {
536
+ signalType: "trace",
537
+ surface: "sdk-retry",
538
+ eventName: context.willRetry ? "sdk.retry" : context.error ? "sdk.request.error" : "sdk.request.complete",
539
+ severity: context.error ? context.willRetry ? "warn" : "error" : "info",
540
+ durationMs: context.durationMs,
541
+ metricName: "sdk.request.duration_ms",
542
+ metricValue: context.durationMs,
543
+ correlationId: context.correlationId ?? context.requestId,
544
+ policyTraceId: context.policyTraceId ?? null,
545
+ tenantId: context.headers.get("x-lucern-tenant-id") ?? context.headers.get("x-lucern-tenant") ?? void 0,
546
+ workspaceId: context.headers.get("x-lucern-workspace-id") ?? context.headers.get("x-lucern-workspace") ?? void 0,
547
+ attributes: {
548
+ service: "lucern-sdk",
549
+ operation: "gateway.request",
550
+ path: context.path,
551
+ httpMethod: context.method,
552
+ httpStatus: context.status,
553
+ attempt: context.attempt,
554
+ maxRetries: context.maxRetries,
555
+ retryReason: retry.reason,
556
+ retryAfterMs: context.retryAfterMs ?? retry.retryAfterMs,
557
+ willRetry: context.willRetry,
558
+ retryable: retry.retryable,
559
+ errorName: context.error instanceof Error ? context.error.name : void 0,
560
+ errorMessage: context.error instanceof Error ? context.error.message : void 0
561
+ }
562
+ });
563
+ }
382
564
  async function parsePayload(response) {
383
565
  const text = await response.text();
384
566
  if (!text) {
@@ -394,11 +576,11 @@ function createGatewayRequestClient(config = {}) {
394
576
  if (typeof requestTimeoutMs === "number") {
395
577
  return requestTimeoutMs;
396
578
  }
397
- const methodTimeoutMs = config.timeoutMsByMethod?.[method];
579
+ const methodTimeoutMs = requestTimeoutByMethod?.[method];
398
580
  if (typeof methodTimeoutMs === "number") {
399
581
  return methodTimeoutMs;
400
582
  }
401
- return config.timeoutMs ?? 15e3;
583
+ return defaultRequestTimeoutMs;
402
584
  }
403
585
  function tryParseGatewayEnvelopeJson(text) {
404
586
  const trimmed = text.trim();
@@ -419,8 +601,8 @@ function createGatewayRequestClient(config = {}) {
419
601
  const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
420
602
  const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
421
603
  const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
422
- const details = redactJsonDiagnosticValue(
423
- failure?.details ?? legacyError?.details
604
+ const details = runtime.redaction(
605
+ redactJsonDiagnosticValue(failure?.details ?? legacyError?.details)
424
606
  );
425
607
  const policySummary = readPolicySummaryFromDetails(details);
426
608
  const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
@@ -490,7 +672,7 @@ function createGatewayRequestClient(config = {}) {
490
672
  failure
491
673
  });
492
674
  const willRetry = attempt < maxRetries && retry.retryable;
493
- await config.onResponse?.({
675
+ const responseContext2 = {
494
676
  ...hookRequestContext,
495
677
  durationMs: Date.now() - startedAt,
496
678
  status: response.status,
@@ -500,7 +682,9 @@ function createGatewayRequestClient(config = {}) {
500
682
  policyTraceId: apiError.policyTraceId ?? null,
501
683
  retryAfterMs,
502
684
  willRetry
503
- });
685
+ };
686
+ await config.onResponse?.(responseContext2);
687
+ await emitSdkResponseTelemetry(responseContext2);
504
688
  if (willRetry) {
505
689
  lastError = apiError;
506
690
  await delay(
@@ -515,7 +699,7 @@ function createGatewayRequestClient(config = {}) {
515
699
  throw apiError;
516
700
  }
517
701
  const successPayload = payload;
518
- await config.onResponse?.({
702
+ const responseContext = {
519
703
  ...hookRequestContext,
520
704
  durationMs: Date.now() - startedAt,
521
705
  status: response.status,
@@ -525,22 +709,25 @@ function createGatewayRequestClient(config = {}) {
525
709
  idempotentReplay: successPayload.idempotentReplay,
526
710
  retryAfterMs,
527
711
  willRetry: false
528
- });
712
+ };
713
+ await config.onResponse?.(responseContext);
714
+ await emitSdkResponseTelemetry(responseContext);
529
715
  return successPayload;
530
716
  } catch (fetchError) {
531
717
  if (fetchError instanceof LucernApiError) {
532
718
  throw fetchError;
533
719
  }
534
- const retry = classifyRetry({ error: fetchError });
535
- const willRetry = attempt < maxRetries && retry.retryable;
536
- await config.onResponse?.({
720
+ const willRetry = attempt < maxRetries && classifyGatewayErrorForRetry(fetchError);
721
+ const responseContext = {
537
722
  ...hookRequestContext,
538
723
  durationMs: Date.now() - startedAt,
539
724
  error: fetchError,
540
725
  correlationId: requestId,
541
726
  policyTraceId: null,
542
727
  willRetry
543
- });
728
+ };
729
+ await config.onResponse?.(responseContext);
730
+ await emitSdkResponseTelemetry(responseContext);
544
731
  lastError = fetchError;
545
732
  if (willRetry) {
546
733
  await delay(computeRetryDelayMs({ attempt }));
@@ -9332,7 +9519,7 @@ function createToolRegistryClient(config = {}) {
9332
9519
  }
9333
9520
 
9334
9521
  // src/version.ts
9335
- var LUCERN_SDK_VERSION = "1.0.1";
9522
+ var LUCERN_SDK_VERSION = "1.0.2";
9336
9523
 
9337
9524
  // src/workflowClient.ts
9338
9525
  function normalizeLensQuery(value) {