@lucern/sdk 1.0.1 → 1.0.3

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 (176) hide show
  1. package/CHANGELOG.md +7 -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/proof-attestation.json +45 -0
  142. package/dist/questions/index.d.ts +1 -0
  143. package/dist/questions/index.js +214 -27
  144. package/dist/questions/index.js.map +1 -1
  145. package/dist/reportsClient.d.ts +1 -0
  146. package/dist/reportsClient.js +213 -26
  147. package/dist/reportsClient.js.map +1 -1
  148. package/dist/schemaClient.d.ts +1 -0
  149. package/dist/schemaClient.js +213 -26
  150. package/dist/schemaClient.js.map +1 -1
  151. package/dist/sdkSurface.d.ts +1 -0
  152. package/dist/sourcesClient.d.ts +1 -0
  153. package/dist/sourcesClient.js +213 -26
  154. package/dist/sourcesClient.js.map +1 -1
  155. package/dist/telemetryClient.d.ts +1 -0
  156. package/dist/telemetryClient.js +213 -26
  157. package/dist/telemetryClient.js.map +1 -1
  158. package/dist/toolRegistryClient.d.ts +1 -0
  159. package/dist/toolRegistryClient.js +213 -26
  160. package/dist/toolRegistryClient.js.map +1 -1
  161. package/dist/topics/index.d.ts +1 -0
  162. package/dist/topics/index.js +214 -27
  163. package/dist/topics/index.js.map +1 -1
  164. package/dist/topicsClient.d.ts +1 -0
  165. package/dist/topicsClient.js +213 -26
  166. package/dist/topicsClient.js.map +1 -1
  167. package/dist/version.d.ts +1 -1
  168. package/dist/version.js +1 -1
  169. package/dist/version.js.map +1 -1
  170. package/dist/workflowClient.d.ts +1 -0
  171. package/dist/workflowClient.js +213 -26
  172. package/dist/workflowClient.js.map +1 -1
  173. package/dist/worktrees/index.d.ts +1 -0
  174. package/dist/worktrees/index.js +214 -27
  175. package/dist/worktrees/index.js.map +1 -1
  176. package/package.json +6 -5
@@ -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
  import * as lensFilter_contract from '@lucern/contracts/lens-filter.contract';
@@ -179,6 +181,33 @@ function createCanonicalAuthHeaders(authContext) {
179
181
  }
180
182
 
181
183
  // src/coreClient.ts
184
+ var DEFAULT_GATEWAY_TIMEOUT_MS = 15e3;
185
+ var DEFAULT_GATEWAY_MAX_RETRIES = 2;
186
+ var DEFAULT_ENV_TIMEOUT_MS = "LUCERN_REQUEST_TIMEOUT_MS";
187
+ var DEFAULT_ENV_MAX_RETRIES = "LUCERN_GATEWAY_MAX_RETRIES";
188
+ var ENV_TIMEOUT_BY_METHOD_PREFIX = "LUCERN_REQUEST_TIMEOUT_MS_";
189
+ var GatewayTimeoutError = class extends Error {
190
+ retryable = true;
191
+ timeoutMs;
192
+ constructor(timeoutMs) {
193
+ super(`Request timed out after ${timeoutMs}ms`);
194
+ this.name = "AbortError";
195
+ this.timeoutMs = timeoutMs;
196
+ }
197
+ };
198
+ var GatewayTransportError = class extends Error {
199
+ retryable;
200
+ cause;
201
+ constructor(message, options) {
202
+ super(message);
203
+ this.name = "GatewayTransportError";
204
+ this.retryable = options?.retryable ?? true;
205
+ this.cause = options?.cause;
206
+ }
207
+ };
208
+ function isGatewayRetryableError(error) {
209
+ return error instanceof GatewayTimeoutError && error.retryable || error instanceof GatewayTransportError && error.retryable || false;
210
+ }
182
211
  var LucernApiError = class extends Error {
183
212
  code;
184
213
  status;
@@ -245,6 +274,99 @@ function generatePortableRequestId() {
245
274
  8
246
275
  ).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
247
276
  }
277
+ function resolveEnvironment() {
278
+ const processEnv = typeof globalThis === "object" && globalThis !== null && "process" in globalThis ? globalThis.process : void 0;
279
+ const env = processEnv !== void 0 && typeof processEnv === "object" && processEnv !== null && typeof processEnv.env === "object" ? processEnv.env : void 0;
280
+ return {
281
+ get: (name) => {
282
+ const value = env?.[name];
283
+ return typeof value === "string" && value.length > 0 ? value : void 0;
284
+ }
285
+ };
286
+ }
287
+ function telemetryEnvironmentRecord(environment) {
288
+ const names = [
289
+ "LUCERN_TELEMETRY_ENABLED",
290
+ "AXIOM_TELEMETRY_ENABLED",
291
+ "LUCERN_AXIOM_TOKEN",
292
+ "AXIOM_TOKEN",
293
+ "LUCERN_AXIOM_EVENTS_DATASET",
294
+ "LUCERN_AXIOM_DATASET",
295
+ "AXIOM_EVENTS_DATASET",
296
+ "AXIOM_DATASET",
297
+ "LUCERN_AXIOM_API_URL",
298
+ "AXIOM_URL",
299
+ "LUCERN_ENVIRONMENT",
300
+ "NODE_ENV",
301
+ "LUCERN_RELEASE",
302
+ "SENTRY_RELEASE",
303
+ "VERCEL_GIT_COMMIT_SHA"
304
+ ];
305
+ return Object.fromEntries(
306
+ names.map((name) => [name, environment.get(name)])
307
+ );
308
+ }
309
+ function resolveRequestProfile(config, environment) {
310
+ const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
311
+ const parsedMaxRetries = parseIntegerFromString(
312
+ config.maxRetries,
313
+ environment.get(DEFAULT_ENV_MAX_RETRIES)
314
+ );
315
+ const parsedTimeoutMs = parseIntegerFromString(
316
+ config.timeoutMs,
317
+ environment.get(DEFAULT_ENV_TIMEOUT_MS)
318
+ );
319
+ const methodTimeouts = {
320
+ ...config.timeoutMsByMethod
321
+ };
322
+ for (const method of ["GET", "POST", "PUT", "PATCH", "DELETE"]) {
323
+ const envKey = `${ENV_TIMEOUT_BY_METHOD_PREFIX}${method}`;
324
+ const raw = environment.get(envKey);
325
+ if (!raw || methodTimeouts[method] !== void 0) {
326
+ continue;
327
+ }
328
+ const parsed = parseIntegerFromString(void 0, raw);
329
+ if (typeof parsed === "number") {
330
+ methodTimeouts[method] = parsed;
331
+ }
332
+ }
333
+ return {
334
+ maxRetries: parsedMaxRetries ?? DEFAULT_GATEWAY_MAX_RETRIES,
335
+ timeoutMs: parsedTimeoutMs ?? DEFAULT_GATEWAY_TIMEOUT_MS,
336
+ timeoutMsByMethod: methodTimeouts,
337
+ requestIdFactory
338
+ };
339
+ }
340
+ function createGatewayRuntime(config, environment) {
341
+ return {
342
+ fetch: config.fetchImpl ?? fetch,
343
+ now: () => Date.now(),
344
+ sleep: (ms) => delay(ms),
345
+ env: environment,
346
+ redaction: resolveRequestRedactionValue,
347
+ profile: resolveRequestProfile(config, environment)
348
+ };
349
+ }
350
+ function parseIntegerFromString(value, rawValue) {
351
+ if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
352
+ return value;
353
+ }
354
+ if (typeof rawValue !== "string" || !rawValue.trim()) {
355
+ return void 0;
356
+ }
357
+ const parsed = Number.parseInt(rawValue, 10);
358
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
359
+ }
360
+ function resolveRequestRedactionValue(value) {
361
+ return redactDiagnosticValue(value);
362
+ }
363
+ function resolveGatewayBaseUrl(configBaseUrl, environment) {
364
+ const envBaseUrl = environment.get("LUCERN_API_URL") ?? environment.get("LUCERN_BASE_URL") ?? environment.get("LUCERN_GATEWAY_BASE_URL");
365
+ return (configBaseUrl ?? envBaseUrl ?? "").replace(/\/+$/, "");
366
+ }
367
+ function normalizeGatewayEnvironment(value) {
368
+ return value === "sandbox" || value === "production" ? value : void 0;
369
+ }
248
370
  var randomIdempotencyKey = generatePortableRequestId;
249
371
  function fallbackErrorCode(status) {
250
372
  if (status === 401) {
@@ -284,10 +406,8 @@ function computeRetryDelayMs(args) {
284
406
  const jitterWindow = Math.max(250, Math.round(baseDelay * 0.25));
285
407
  return baseDelay + Math.round(Math.random() * jitterWindow);
286
408
  }
287
- function timeoutError(timeoutMs) {
288
- const error = new Error(`Request timed out after ${timeoutMs}ms`);
289
- error.name = "AbortError";
290
- return error;
409
+ function classifyGatewayErrorForRetry(error) {
410
+ return isGatewayRetryableError(error) || classifyRetry({ error }).retryable;
291
411
  }
292
412
  function isRecord(value) {
293
413
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -342,10 +462,18 @@ function cleanHeaderValue(value) {
342
462
  return normalized ? normalized : void 0;
343
463
  }
344
464
  function createGatewayRequestClient(config = {}) {
345
- const fetchImpl = config.fetchImpl ?? fetch;
346
- const baseUrl = config.baseUrl?.replace(/\/+$/, "") ?? "";
347
- const maxRetries = config.maxRetries ?? 2;
348
- const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
465
+ const env = resolveEnvironment();
466
+ const runtime = createGatewayRuntime(config, env);
467
+ const baseUrl = resolveGatewayBaseUrl(config.baseUrl, env);
468
+ const maxRetries = runtime.profile.maxRetries;
469
+ const requestIdFactory = runtime.profile.requestIdFactory;
470
+ const requestTimeoutByMethod = runtime.profile.timeoutMsByMethod;
471
+ const defaultRequestTimeoutMs = runtime.profile.timeoutMs;
472
+ const normalizedEnvironment = normalizeGatewayEnvironment(config.environment);
473
+ const telemetryExporter = config.telemetryEnabled === false ? null : config.telemetryExporter ?? createTelemetryExporterFromEnv(telemetryEnvironmentRecord(env), {
474
+ service: "lucern-sdk",
475
+ environment: normalizedEnvironment
476
+ });
349
477
  async function resolveAuthHeaders() {
350
478
  const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
351
479
  const headers = new Headers(provided);
@@ -357,7 +485,7 @@ function createGatewayRequestClient(config = {}) {
357
485
  };
358
486
  setIfAbsent("x-lucern-key", config.apiKey);
359
487
  setIfAbsent("x-lucern-session-token", config.userToken);
360
- setIfAbsent("x-lucern-environment", config.environment);
488
+ setIfAbsent("x-lucern-environment", normalizedEnvironment);
361
489
  setIfAbsent("x-lucern-clerk-id", config.clerkId);
362
490
  setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
363
491
  setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
@@ -372,19 +500,73 @@ function createGatewayRequestClient(config = {}) {
372
500
  return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
373
501
  }
374
502
  async function fetchWithTimeout(url, init, timeoutMs) {
503
+ const normalizeTransportError = (error, isTimeout) => {
504
+ if (isTimeout) {
505
+ return new GatewayTimeoutError(timeoutMs);
506
+ }
507
+ return error instanceof GatewayTimeoutError || error instanceof GatewayTransportError ? error : new GatewayTransportError(
508
+ error instanceof Error ? error.message : "Gateway transport error",
509
+ {
510
+ cause: error,
511
+ retryable: classifyGatewayErrorForRetry(error)
512
+ }
513
+ );
514
+ };
375
515
  const controller = new AbortController();
376
516
  const timer = setTimeout(() => controller.abort(), timeoutMs);
517
+ const requestEffect = Effect.tryPromise({
518
+ try: () => runtime.fetch(url, { ...init, signal: controller.signal }),
519
+ catch: (error) => normalizeTransportError(error, controller.signal.aborted)
520
+ });
377
521
  try {
378
- return await fetchImpl(url, { ...init, signal: controller.signal });
379
- } catch (error) {
380
- if (controller.signal.aborted) {
381
- throw timeoutError(timeoutMs);
522
+ const exit = await Effect.runPromiseExit(requestEffect);
523
+ if (Exit.isSuccess(exit)) {
524
+ return exit.value;
382
525
  }
383
- throw error;
526
+ const failure = Array.from(Cause.failures(exit.cause))[0];
527
+ if (failure !== void 0) {
528
+ throw failure;
529
+ }
530
+ throw Cause.squash(exit.cause);
384
531
  } finally {
385
532
  clearTimeout(timer);
386
533
  }
387
534
  }
535
+ async function emitSdkResponseTelemetry(context) {
536
+ const retry = classifyRetry({
537
+ status: context.status,
538
+ error: context.error,
539
+ retryAfter: context.retryAfterMs !== null && context.retryAfterMs !== void 0 ? String(context.retryAfterMs / 1e3) : void 0
540
+ });
541
+ await emitTelemetrySignal(telemetryExporter, {
542
+ signalType: "trace",
543
+ surface: "sdk-retry",
544
+ eventName: context.willRetry ? "sdk.retry" : context.error ? "sdk.request.error" : "sdk.request.complete",
545
+ severity: context.error ? context.willRetry ? "warn" : "error" : "info",
546
+ durationMs: context.durationMs,
547
+ metricName: "sdk.request.duration_ms",
548
+ metricValue: context.durationMs,
549
+ correlationId: context.correlationId ?? context.requestId,
550
+ policyTraceId: context.policyTraceId ?? null,
551
+ tenantId: context.headers.get("x-lucern-tenant-id") ?? context.headers.get("x-lucern-tenant") ?? void 0,
552
+ workspaceId: context.headers.get("x-lucern-workspace-id") ?? context.headers.get("x-lucern-workspace") ?? void 0,
553
+ attributes: {
554
+ service: "lucern-sdk",
555
+ operation: "gateway.request",
556
+ path: context.path,
557
+ httpMethod: context.method,
558
+ httpStatus: context.status,
559
+ attempt: context.attempt,
560
+ maxRetries: context.maxRetries,
561
+ retryReason: retry.reason,
562
+ retryAfterMs: context.retryAfterMs ?? retry.retryAfterMs,
563
+ willRetry: context.willRetry,
564
+ retryable: retry.retryable,
565
+ errorName: context.error instanceof Error ? context.error.name : void 0,
566
+ errorMessage: context.error instanceof Error ? context.error.message : void 0
567
+ }
568
+ });
569
+ }
388
570
  async function parsePayload(response) {
389
571
  const text = await response.text();
390
572
  if (!text) {
@@ -400,11 +582,11 @@ function createGatewayRequestClient(config = {}) {
400
582
  if (typeof requestTimeoutMs === "number") {
401
583
  return requestTimeoutMs;
402
584
  }
403
- const methodTimeoutMs = config.timeoutMsByMethod?.[method];
585
+ const methodTimeoutMs = requestTimeoutByMethod?.[method];
404
586
  if (typeof methodTimeoutMs === "number") {
405
587
  return methodTimeoutMs;
406
588
  }
407
- return config.timeoutMs ?? 15e3;
589
+ return defaultRequestTimeoutMs;
408
590
  }
409
591
  function tryParseGatewayEnvelopeJson(text) {
410
592
  const trimmed = text.trim();
@@ -425,8 +607,8 @@ function createGatewayRequestClient(config = {}) {
425
607
  const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
426
608
  const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
427
609
  const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
428
- const details = redactJsonDiagnosticValue(
429
- failure?.details ?? legacyError?.details
610
+ const details = runtime.redaction(
611
+ redactJsonDiagnosticValue(failure?.details ?? legacyError?.details)
430
612
  );
431
613
  const policySummary = readPolicySummaryFromDetails(details);
432
614
  const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
@@ -496,7 +678,7 @@ function createGatewayRequestClient(config = {}) {
496
678
  failure
497
679
  });
498
680
  const willRetry = attempt < maxRetries && retry.retryable;
499
- await config.onResponse?.({
681
+ const responseContext2 = {
500
682
  ...hookRequestContext,
501
683
  durationMs: Date.now() - startedAt,
502
684
  status: response.status,
@@ -506,7 +688,9 @@ function createGatewayRequestClient(config = {}) {
506
688
  policyTraceId: apiError.policyTraceId ?? null,
507
689
  retryAfterMs,
508
690
  willRetry
509
- });
691
+ };
692
+ await config.onResponse?.(responseContext2);
693
+ await emitSdkResponseTelemetry(responseContext2);
510
694
  if (willRetry) {
511
695
  lastError = apiError;
512
696
  await delay(
@@ -521,7 +705,7 @@ function createGatewayRequestClient(config = {}) {
521
705
  throw apiError;
522
706
  }
523
707
  const successPayload = payload;
524
- await config.onResponse?.({
708
+ const responseContext = {
525
709
  ...hookRequestContext,
526
710
  durationMs: Date.now() - startedAt,
527
711
  status: response.status,
@@ -531,22 +715,25 @@ function createGatewayRequestClient(config = {}) {
531
715
  idempotentReplay: successPayload.idempotentReplay,
532
716
  retryAfterMs,
533
717
  willRetry: false
534
- });
718
+ };
719
+ await config.onResponse?.(responseContext);
720
+ await emitSdkResponseTelemetry(responseContext);
535
721
  return successPayload;
536
722
  } catch (fetchError) {
537
723
  if (fetchError instanceof LucernApiError) {
538
724
  throw fetchError;
539
725
  }
540
- const retry = classifyRetry({ error: fetchError });
541
- const willRetry = attempt < maxRetries && retry.retryable;
542
- await config.onResponse?.({
726
+ const willRetry = attempt < maxRetries && classifyGatewayErrorForRetry(fetchError);
727
+ const responseContext = {
543
728
  ...hookRequestContext,
544
729
  durationMs: Date.now() - startedAt,
545
730
  error: fetchError,
546
731
  correlationId: requestId,
547
732
  policyTraceId: null,
548
733
  willRetry
549
- });
734
+ };
735
+ await config.onResponse?.(responseContext);
736
+ await emitSdkResponseTelemetry(responseContext);
550
737
  lastError = fetchError;
551
738
  if (willRetry) {
552
739
  await delay(computeRetryDelayMs({ attempt }));
@@ -9338,7 +9525,7 @@ function createToolRegistryClient(config = {}) {
9338
9525
  }
9339
9526
 
9340
9527
  // src/version.ts
9341
- var LUCERN_SDK_VERSION = "1.0.1";
9528
+ var LUCERN_SDK_VERSION = "1.0.3";
9342
9529
 
9343
9530
  // src/workflowClient.ts
9344
9531
  function normalizeLensQuery(value) {