@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.
- package/CHANGELOG.md +7 -0
- package/dist/accessControl.d.ts +1 -0
- package/dist/accessControl.js +213 -26
- package/dist/accessControl.js.map +1 -1
- package/dist/adminClient.d.ts +1 -0
- package/dist/adminClient.js +213 -26
- package/dist/adminClient.js.map +1 -1
- package/dist/answersClient.d.ts +1 -0
- package/dist/answersClient.js +213 -26
- package/dist/answersClient.js.map +1 -1
- package/dist/audiencesClient.d.ts +1 -0
- package/dist/audiencesClient.js +213 -26
- package/dist/audiencesClient.js.map +1 -1
- package/dist/auditClient.d.ts +1 -0
- package/dist/auditClient.js +213 -26
- package/dist/auditClient.js.map +1 -1
- package/dist/authDeviceClient.d.ts +1 -0
- package/dist/beliefs/index.d.ts +1 -0
- package/dist/beliefs/index.js +214 -27
- package/dist/beliefs/index.js.map +1 -1
- package/dist/beliefsClient.d.ts +1 -0
- package/dist/beliefsClient.js +213 -26
- package/dist/beliefsClient.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.js +214 -27
- package/dist/client.js.map +1 -1
- package/dist/clientConfig.d.ts +1 -0
- package/dist/clientEvidenceCompat.d.ts +1 -0
- package/dist/clientKnowledgeNamespaces.d.ts +1 -0
- package/dist/clientLocalHelpers.d.ts +1 -0
- package/dist/clientLocalHelpers.js +2 -0
- package/dist/clientLocalHelpers.js.map +1 -1
- package/dist/clientPlatformNamespaces.d.ts +1 -0
- package/dist/clientRuntime.d.ts +1 -0
- package/dist/clientWorkflowNamespaces.d.ts +1 -0
- package/dist/contextClient.d.ts +1 -0
- package/dist/contextClient.js +213 -26
- package/dist/contextClient.js.map +1 -1
- package/dist/contradictions/index.d.ts +1 -0
- package/dist/contradictions/index.js +214 -27
- package/dist/contradictions/index.js.map +1 -1
- package/dist/control-plane.d.ts +1 -0
- package/dist/control-plane.js +213 -26
- package/dist/control-plane.js.map +1 -1
- package/dist/coreClient.d.ts +25 -1
- package/dist/coreClient.js +217 -27
- package/dist/coreClient.js.map +1 -1
- package/dist/decisions/index.d.ts +1 -0
- package/dist/decisions/index.js +214 -27
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisionsClient.d.ts +1 -0
- package/dist/decisionsClient.js +213 -26
- package/dist/decisionsClient.js.map +1 -1
- package/dist/edges/index.d.ts +1 -0
- package/dist/edges/index.js +214 -27
- package/dist/edges/index.js.map +1 -1
- package/dist/embeddingsClient.d.ts +1 -0
- package/dist/embeddingsClient.js +213 -26
- package/dist/embeddingsClient.js.map +1 -1
- package/dist/eventingClient.d.ts +1 -0
- package/dist/eventingClient.js +213 -26
- package/dist/eventingClient.js.map +1 -1
- package/dist/eventsCore.d.ts +1 -0
- package/dist/eventsCore.js +213 -26
- package/dist/eventsCore.js.map +1 -1
- package/dist/evidence/index.d.ts +1 -0
- package/dist/evidence/index.js +214 -27
- package/dist/evidence/index.js.map +1 -1
- package/dist/evidenceClient.d.ts +1 -0
- package/dist/evidenceClient.js +213 -26
- package/dist/evidenceClient.js.map +1 -1
- package/dist/functionSurface.d.ts +1 -0
- package/dist/functionSurface.js +213 -26
- package/dist/functionSurface.js.map +1 -1
- package/dist/functionSurfaceClient.d.ts +1 -0
- package/dist/functionSurfaceClient.js +213 -26
- package/dist/functionSurfaceClient.js.map +1 -1
- package/dist/gatewayFacades.d.ts +1 -0
- package/dist/gatewayFacades.factories.d.ts +1 -0
- package/dist/gatewayFacades.factories.js +213 -26
- package/dist/gatewayFacades.factories.js.map +1 -1
- package/dist/gatewayFacades.js +213 -26
- package/dist/gatewayFacades.js.map +1 -1
- package/dist/graphAnalysisClient.d.ts +1 -0
- package/dist/graphAnalysisClient.js +213 -26
- package/dist/graphAnalysisClient.js.map +1 -1
- package/dist/graphClient.d.ts +1 -0
- package/dist/graphClient.js +213 -26
- package/dist/graphClient.js.map +1 -1
- package/dist/graphRecommendationsClient.d.ts +1 -0
- package/dist/graphRecommendationsClient.js +213 -26
- package/dist/graphRecommendationsClient.js.map +1 -1
- package/dist/graphStateClassifierClient.d.ts +1 -0
- package/dist/graphStateClassifierClient.js +213 -26
- package/dist/graphStateClassifierClient.js.map +1 -1
- package/dist/harnessClient.d.ts +1 -0
- package/dist/harnessClient.js +213 -26
- package/dist/harnessClient.js.map +1 -1
- package/dist/identityClient.d.ts +1 -0
- package/dist/identityClient.js +213 -26
- package/dist/identityClient.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +237 -28
- package/dist/index.js.map +1 -1
- package/dist/jobsClient.d.ts +1 -0
- package/dist/jobsClient.js +213 -26
- package/dist/jobsClient.js.map +1 -1
- package/dist/learningClient.d.ts +1 -0
- package/dist/learningClient.js +213 -26
- package/dist/learningClient.js.map +1 -1
- package/dist/lenses/index.d.ts +1 -0
- package/dist/lenses/index.js +214 -27
- package/dist/lenses/index.js.map +1 -1
- package/dist/mcpClient.d.ts +1 -0
- package/dist/mcpClient.js +213 -26
- package/dist/mcpClient.js.map +1 -1
- package/dist/modelRuntimeClient.d.ts +1 -0
- package/dist/modelRuntimeClient.js +213 -26
- package/dist/modelRuntimeClient.js.map +1 -1
- package/dist/nodes/index.d.ts +1 -0
- package/dist/nodes/index.js +214 -27
- package/dist/nodes/index.js.map +1 -1
- package/dist/ontologies/index.d.ts +1 -0
- package/dist/ontologies/index.js +214 -27
- package/dist/ontologies/index.js.map +1 -1
- package/dist/ontologyClient.d.ts +1 -0
- package/dist/ontologyClient.js +213 -26
- package/dist/ontologyClient.js.map +1 -1
- package/dist/ontologyLinksClient.d.ts +1 -0
- package/dist/ontologyLinksClient.js +213 -26
- package/dist/ontologyLinksClient.js.map +1 -1
- package/dist/orgGraphSearchClient.d.ts +1 -0
- package/dist/orgGraphSearchClient.js +213 -26
- package/dist/orgGraphSearchClient.js.map +1 -1
- package/dist/packsClient.d.ts +1 -0
- package/dist/packsClient.js +213 -26
- package/dist/packsClient.js.map +1 -1
- package/dist/policyClient.d.ts +1 -0
- package/dist/policyClient.js +213 -26
- package/dist/policyClient.js.map +1 -1
- package/dist/proof-attestation.json +45 -0
- package/dist/questions/index.d.ts +1 -0
- package/dist/questions/index.js +214 -27
- package/dist/questions/index.js.map +1 -1
- package/dist/reportsClient.d.ts +1 -0
- package/dist/reportsClient.js +213 -26
- package/dist/reportsClient.js.map +1 -1
- package/dist/schemaClient.d.ts +1 -0
- package/dist/schemaClient.js +213 -26
- package/dist/schemaClient.js.map +1 -1
- package/dist/sdkSurface.d.ts +1 -0
- package/dist/sourcesClient.d.ts +1 -0
- package/dist/sourcesClient.js +213 -26
- package/dist/sourcesClient.js.map +1 -1
- package/dist/telemetryClient.d.ts +1 -0
- package/dist/telemetryClient.js +213 -26
- package/dist/telemetryClient.js.map +1 -1
- package/dist/toolRegistryClient.d.ts +1 -0
- package/dist/toolRegistryClient.js +213 -26
- package/dist/toolRegistryClient.js.map +1 -1
- package/dist/topics/index.d.ts +1 -0
- package/dist/topics/index.js +214 -27
- package/dist/topics/index.js.map +1 -1
- package/dist/topicsClient.d.ts +1 -0
- package/dist/topicsClient.js +213 -26
- package/dist/topicsClient.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/workflowClient.d.ts +1 -0
- package/dist/workflowClient.js +213 -26
- package/dist/workflowClient.js.map +1 -1
- package/dist/worktrees/index.d.ts +1 -0
- package/dist/worktrees/index.js +214 -27
- package/dist/worktrees/index.js.map +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ 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.3] - 2026-05-27
|
|
9
|
+
- Release notes pending.
|
|
10
|
+
|
|
11
|
+
## [1.0.2] - 2026-05-27
|
|
12
|
+
- Campaign 1 wrap-up release with expanded CLI targeting and observability pilot surfaces.
|
|
13
|
+
|
|
14
|
+
|
|
8
15
|
## [1.0.1] - 2026-05-26
|
|
9
16
|
- Publish the Campaign 1 runtime lifecycle, graph-native CLI, Effect runtime,
|
|
10
17
|
XState lifecycle, and transport-core package line as a coherent patch release.
|
package/dist/accessControl.d.ts
CHANGED
|
@@ -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';
|
package/dist/accessControl.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
|
|
|
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
|
|
276
|
-
|
|
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
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
const
|
|
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",
|
|
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
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
throw timeoutError(timeoutMs);
|
|
510
|
+
const exit = await Effect.runPromiseExit(requestEffect);
|
|
511
|
+
if (Exit.isSuccess(exit)) {
|
|
512
|
+
return exit.value;
|
|
370
513
|
}
|
|
371
|
-
|
|
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 =
|
|
573
|
+
const methodTimeoutMs = requestTimeoutByMethod?.[method];
|
|
392
574
|
if (typeof methodTimeoutMs === "number") {
|
|
393
575
|
return methodTimeoutMs;
|
|
394
576
|
}
|
|
395
|
-
return
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
529
|
-
const
|
|
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 }));
|