@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { FUNCTION_SURFACE_METHOD_PATHS, FunctionSurfaceClientConfig, FunctionSurfaceInput, FunctionSurfaceResult, createFunctionSurfaceClient } from './functionSurface.js';
|
|
2
2
|
import './coreClient.js';
|
|
3
|
+
import '@lucern/transport-core';
|
|
3
4
|
import './authContext.js';
|
|
4
5
|
import './contracts/auth-session.contract.js';
|
|
5
6
|
import './types.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/coreClient.ts
|
|
5
7
|
|
|
@@ -171,6 +173,33 @@ function createCanonicalAuthHeaders(authContext) {
|
|
|
171
173
|
}
|
|
172
174
|
|
|
173
175
|
// src/coreClient.ts
|
|
176
|
+
var DEFAULT_GATEWAY_TIMEOUT_MS = 15e3;
|
|
177
|
+
var DEFAULT_GATEWAY_MAX_RETRIES = 2;
|
|
178
|
+
var DEFAULT_ENV_TIMEOUT_MS = "LUCERN_REQUEST_TIMEOUT_MS";
|
|
179
|
+
var DEFAULT_ENV_MAX_RETRIES = "LUCERN_GATEWAY_MAX_RETRIES";
|
|
180
|
+
var ENV_TIMEOUT_BY_METHOD_PREFIX = "LUCERN_REQUEST_TIMEOUT_MS_";
|
|
181
|
+
var GatewayTimeoutError = class extends Error {
|
|
182
|
+
retryable = true;
|
|
183
|
+
timeoutMs;
|
|
184
|
+
constructor(timeoutMs) {
|
|
185
|
+
super(`Request timed out after ${timeoutMs}ms`);
|
|
186
|
+
this.name = "AbortError";
|
|
187
|
+
this.timeoutMs = timeoutMs;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
var GatewayTransportError = class extends Error {
|
|
191
|
+
retryable;
|
|
192
|
+
cause;
|
|
193
|
+
constructor(message, options) {
|
|
194
|
+
super(message);
|
|
195
|
+
this.name = "GatewayTransportError";
|
|
196
|
+
this.retryable = options?.retryable ?? true;
|
|
197
|
+
this.cause = options?.cause;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
function isGatewayRetryableError(error) {
|
|
201
|
+
return error instanceof GatewayTimeoutError && error.retryable || error instanceof GatewayTransportError && error.retryable || false;
|
|
202
|
+
}
|
|
174
203
|
var LucernApiError = class extends Error {
|
|
175
204
|
code;
|
|
176
205
|
status;
|
|
@@ -217,6 +246,99 @@ function generatePortableRequestId() {
|
|
|
217
246
|
8
|
|
218
247
|
).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
219
248
|
}
|
|
249
|
+
function resolveEnvironment() {
|
|
250
|
+
const processEnv = typeof globalThis === "object" && globalThis !== null && "process" in globalThis ? globalThis.process : void 0;
|
|
251
|
+
const env = processEnv !== void 0 && typeof processEnv === "object" && processEnv !== null && typeof processEnv.env === "object" ? processEnv.env : void 0;
|
|
252
|
+
return {
|
|
253
|
+
get: (name) => {
|
|
254
|
+
const value = env?.[name];
|
|
255
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function telemetryEnvironmentRecord(environment) {
|
|
260
|
+
const names = [
|
|
261
|
+
"LUCERN_TELEMETRY_ENABLED",
|
|
262
|
+
"AXIOM_TELEMETRY_ENABLED",
|
|
263
|
+
"LUCERN_AXIOM_TOKEN",
|
|
264
|
+
"AXIOM_TOKEN",
|
|
265
|
+
"LUCERN_AXIOM_EVENTS_DATASET",
|
|
266
|
+
"LUCERN_AXIOM_DATASET",
|
|
267
|
+
"AXIOM_EVENTS_DATASET",
|
|
268
|
+
"AXIOM_DATASET",
|
|
269
|
+
"LUCERN_AXIOM_API_URL",
|
|
270
|
+
"AXIOM_URL",
|
|
271
|
+
"LUCERN_ENVIRONMENT",
|
|
272
|
+
"NODE_ENV",
|
|
273
|
+
"LUCERN_RELEASE",
|
|
274
|
+
"SENTRY_RELEASE",
|
|
275
|
+
"VERCEL_GIT_COMMIT_SHA"
|
|
276
|
+
];
|
|
277
|
+
return Object.fromEntries(
|
|
278
|
+
names.map((name) => [name, environment.get(name)])
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
function resolveRequestProfile(config, environment) {
|
|
282
|
+
const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
|
|
283
|
+
const parsedMaxRetries = parseIntegerFromString(
|
|
284
|
+
config.maxRetries,
|
|
285
|
+
environment.get(DEFAULT_ENV_MAX_RETRIES)
|
|
286
|
+
);
|
|
287
|
+
const parsedTimeoutMs = parseIntegerFromString(
|
|
288
|
+
config.timeoutMs,
|
|
289
|
+
environment.get(DEFAULT_ENV_TIMEOUT_MS)
|
|
290
|
+
);
|
|
291
|
+
const methodTimeouts = {
|
|
292
|
+
...config.timeoutMsByMethod
|
|
293
|
+
};
|
|
294
|
+
for (const method of ["GET", "POST", "PUT", "PATCH", "DELETE"]) {
|
|
295
|
+
const envKey = `${ENV_TIMEOUT_BY_METHOD_PREFIX}${method}`;
|
|
296
|
+
const raw = environment.get(envKey);
|
|
297
|
+
if (!raw || methodTimeouts[method] !== void 0) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const parsed = parseIntegerFromString(void 0, raw);
|
|
301
|
+
if (typeof parsed === "number") {
|
|
302
|
+
methodTimeouts[method] = parsed;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
maxRetries: parsedMaxRetries ?? DEFAULT_GATEWAY_MAX_RETRIES,
|
|
307
|
+
timeoutMs: parsedTimeoutMs ?? DEFAULT_GATEWAY_TIMEOUT_MS,
|
|
308
|
+
timeoutMsByMethod: methodTimeouts,
|
|
309
|
+
requestIdFactory
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function createGatewayRuntime(config, environment) {
|
|
313
|
+
return {
|
|
314
|
+
fetch: config.fetchImpl ?? fetch,
|
|
315
|
+
now: () => Date.now(),
|
|
316
|
+
sleep: (ms) => delay(ms),
|
|
317
|
+
env: environment,
|
|
318
|
+
redaction: resolveRequestRedactionValue,
|
|
319
|
+
profile: resolveRequestProfile(config, environment)
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function parseIntegerFromString(value, rawValue) {
|
|
323
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
|
|
324
|
+
return value;
|
|
325
|
+
}
|
|
326
|
+
if (typeof rawValue !== "string" || !rawValue.trim()) {
|
|
327
|
+
return void 0;
|
|
328
|
+
}
|
|
329
|
+
const parsed = Number.parseInt(rawValue, 10);
|
|
330
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
331
|
+
}
|
|
332
|
+
function resolveRequestRedactionValue(value) {
|
|
333
|
+
return redactDiagnosticValue(value);
|
|
334
|
+
}
|
|
335
|
+
function resolveGatewayBaseUrl(configBaseUrl, environment) {
|
|
336
|
+
const envBaseUrl = environment.get("LUCERN_API_URL") ?? environment.get("LUCERN_BASE_URL") ?? environment.get("LUCERN_GATEWAY_BASE_URL");
|
|
337
|
+
return (configBaseUrl ?? envBaseUrl ?? "").replace(/\/+$/, "");
|
|
338
|
+
}
|
|
339
|
+
function normalizeGatewayEnvironment(value) {
|
|
340
|
+
return value === "sandbox" || value === "production" ? value : void 0;
|
|
341
|
+
}
|
|
220
342
|
var randomIdempotencyKey = generatePortableRequestId;
|
|
221
343
|
function fallbackErrorCode(status) {
|
|
222
344
|
if (status === 401) {
|
|
@@ -256,10 +378,8 @@ function computeRetryDelayMs(args) {
|
|
|
256
378
|
const jitterWindow = Math.max(250, Math.round(baseDelay * 0.25));
|
|
257
379
|
return baseDelay + Math.round(Math.random() * jitterWindow);
|
|
258
380
|
}
|
|
259
|
-
function
|
|
260
|
-
|
|
261
|
-
error.name = "AbortError";
|
|
262
|
-
return error;
|
|
381
|
+
function classifyGatewayErrorForRetry(error) {
|
|
382
|
+
return isGatewayRetryableError(error) || classifyRetry({ error }).retryable;
|
|
263
383
|
}
|
|
264
384
|
function isRecord(value) {
|
|
265
385
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -314,10 +434,18 @@ function cleanHeaderValue(value) {
|
|
|
314
434
|
return normalized ? normalized : void 0;
|
|
315
435
|
}
|
|
316
436
|
function createGatewayRequestClient(config = {}) {
|
|
317
|
-
const
|
|
318
|
-
const
|
|
319
|
-
const
|
|
320
|
-
const
|
|
437
|
+
const env = resolveEnvironment();
|
|
438
|
+
const runtime = createGatewayRuntime(config, env);
|
|
439
|
+
const baseUrl = resolveGatewayBaseUrl(config.baseUrl, env);
|
|
440
|
+
const maxRetries = runtime.profile.maxRetries;
|
|
441
|
+
const requestIdFactory = runtime.profile.requestIdFactory;
|
|
442
|
+
const requestTimeoutByMethod = runtime.profile.timeoutMsByMethod;
|
|
443
|
+
const defaultRequestTimeoutMs = runtime.profile.timeoutMs;
|
|
444
|
+
const normalizedEnvironment = normalizeGatewayEnvironment(config.environment);
|
|
445
|
+
const telemetryExporter = config.telemetryEnabled === false ? null : config.telemetryExporter ?? createTelemetryExporterFromEnv(telemetryEnvironmentRecord(env), {
|
|
446
|
+
service: "lucern-sdk",
|
|
447
|
+
environment: normalizedEnvironment
|
|
448
|
+
});
|
|
321
449
|
async function resolveAuthHeaders() {
|
|
322
450
|
const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
|
|
323
451
|
const headers = new Headers(provided);
|
|
@@ -329,7 +457,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
329
457
|
};
|
|
330
458
|
setIfAbsent("x-lucern-key", config.apiKey);
|
|
331
459
|
setIfAbsent("x-lucern-session-token", config.userToken);
|
|
332
|
-
setIfAbsent("x-lucern-environment",
|
|
460
|
+
setIfAbsent("x-lucern-environment", normalizedEnvironment);
|
|
333
461
|
setIfAbsent("x-lucern-clerk-id", config.clerkId);
|
|
334
462
|
setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
|
|
335
463
|
setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
|
|
@@ -344,19 +472,73 @@ function createGatewayRequestClient(config = {}) {
|
|
|
344
472
|
return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
|
|
345
473
|
}
|
|
346
474
|
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
475
|
+
const normalizeTransportError = (error, isTimeout) => {
|
|
476
|
+
if (isTimeout) {
|
|
477
|
+
return new GatewayTimeoutError(timeoutMs);
|
|
478
|
+
}
|
|
479
|
+
return error instanceof GatewayTimeoutError || error instanceof GatewayTransportError ? error : new GatewayTransportError(
|
|
480
|
+
error instanceof Error ? error.message : "Gateway transport error",
|
|
481
|
+
{
|
|
482
|
+
cause: error,
|
|
483
|
+
retryable: classifyGatewayErrorForRetry(error)
|
|
484
|
+
}
|
|
485
|
+
);
|
|
486
|
+
};
|
|
347
487
|
const controller = new AbortController();
|
|
348
488
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
489
|
+
const requestEffect = Effect.tryPromise({
|
|
490
|
+
try: () => runtime.fetch(url, { ...init, signal: controller.signal }),
|
|
491
|
+
catch: (error) => normalizeTransportError(error, controller.signal.aborted)
|
|
492
|
+
});
|
|
349
493
|
try {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
throw timeoutError(timeoutMs);
|
|
494
|
+
const exit = await Effect.runPromiseExit(requestEffect);
|
|
495
|
+
if (Exit.isSuccess(exit)) {
|
|
496
|
+
return exit.value;
|
|
354
497
|
}
|
|
355
|
-
|
|
498
|
+
const failure = Array.from(Cause.failures(exit.cause))[0];
|
|
499
|
+
if (failure !== void 0) {
|
|
500
|
+
throw failure;
|
|
501
|
+
}
|
|
502
|
+
throw Cause.squash(exit.cause);
|
|
356
503
|
} finally {
|
|
357
504
|
clearTimeout(timer);
|
|
358
505
|
}
|
|
359
506
|
}
|
|
507
|
+
async function emitSdkResponseTelemetry(context) {
|
|
508
|
+
const retry = classifyRetry({
|
|
509
|
+
status: context.status,
|
|
510
|
+
error: context.error,
|
|
511
|
+
retryAfter: context.retryAfterMs !== null && context.retryAfterMs !== void 0 ? String(context.retryAfterMs / 1e3) : void 0
|
|
512
|
+
});
|
|
513
|
+
await emitTelemetrySignal(telemetryExporter, {
|
|
514
|
+
signalType: "trace",
|
|
515
|
+
surface: "sdk-retry",
|
|
516
|
+
eventName: context.willRetry ? "sdk.retry" : context.error ? "sdk.request.error" : "sdk.request.complete",
|
|
517
|
+
severity: context.error ? context.willRetry ? "warn" : "error" : "info",
|
|
518
|
+
durationMs: context.durationMs,
|
|
519
|
+
metricName: "sdk.request.duration_ms",
|
|
520
|
+
metricValue: context.durationMs,
|
|
521
|
+
correlationId: context.correlationId ?? context.requestId,
|
|
522
|
+
policyTraceId: context.policyTraceId ?? null,
|
|
523
|
+
tenantId: context.headers.get("x-lucern-tenant-id") ?? context.headers.get("x-lucern-tenant") ?? void 0,
|
|
524
|
+
workspaceId: context.headers.get("x-lucern-workspace-id") ?? context.headers.get("x-lucern-workspace") ?? void 0,
|
|
525
|
+
attributes: {
|
|
526
|
+
service: "lucern-sdk",
|
|
527
|
+
operation: "gateway.request",
|
|
528
|
+
path: context.path,
|
|
529
|
+
httpMethod: context.method,
|
|
530
|
+
httpStatus: context.status,
|
|
531
|
+
attempt: context.attempt,
|
|
532
|
+
maxRetries: context.maxRetries,
|
|
533
|
+
retryReason: retry.reason,
|
|
534
|
+
retryAfterMs: context.retryAfterMs ?? retry.retryAfterMs,
|
|
535
|
+
willRetry: context.willRetry,
|
|
536
|
+
retryable: retry.retryable,
|
|
537
|
+
errorName: context.error instanceof Error ? context.error.name : void 0,
|
|
538
|
+
errorMessage: context.error instanceof Error ? context.error.message : void 0
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
360
542
|
async function parsePayload(response) {
|
|
361
543
|
const text = await response.text();
|
|
362
544
|
if (!text) {
|
|
@@ -372,11 +554,11 @@ function createGatewayRequestClient(config = {}) {
|
|
|
372
554
|
if (typeof requestTimeoutMs === "number") {
|
|
373
555
|
return requestTimeoutMs;
|
|
374
556
|
}
|
|
375
|
-
const methodTimeoutMs =
|
|
557
|
+
const methodTimeoutMs = requestTimeoutByMethod?.[method];
|
|
376
558
|
if (typeof methodTimeoutMs === "number") {
|
|
377
559
|
return methodTimeoutMs;
|
|
378
560
|
}
|
|
379
|
-
return
|
|
561
|
+
return defaultRequestTimeoutMs;
|
|
380
562
|
}
|
|
381
563
|
function tryParseGatewayEnvelopeJson(text) {
|
|
382
564
|
const trimmed = text.trim();
|
|
@@ -397,8 +579,8 @@ function createGatewayRequestClient(config = {}) {
|
|
|
397
579
|
const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
|
|
398
580
|
const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
|
|
399
581
|
const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
|
|
400
|
-
const details =
|
|
401
|
-
failure?.details ?? legacyError?.details
|
|
582
|
+
const details = runtime.redaction(
|
|
583
|
+
redactJsonDiagnosticValue(failure?.details ?? legacyError?.details)
|
|
402
584
|
);
|
|
403
585
|
const policySummary = readPolicySummaryFromDetails(details);
|
|
404
586
|
const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
|
|
@@ -468,7 +650,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
468
650
|
failure
|
|
469
651
|
});
|
|
470
652
|
const willRetry = attempt < maxRetries && retry.retryable;
|
|
471
|
-
|
|
653
|
+
const responseContext2 = {
|
|
472
654
|
...hookRequestContext,
|
|
473
655
|
durationMs: Date.now() - startedAt,
|
|
474
656
|
status: response.status,
|
|
@@ -478,7 +660,9 @@ function createGatewayRequestClient(config = {}) {
|
|
|
478
660
|
policyTraceId: apiError.policyTraceId ?? null,
|
|
479
661
|
retryAfterMs,
|
|
480
662
|
willRetry
|
|
481
|
-
}
|
|
663
|
+
};
|
|
664
|
+
await config.onResponse?.(responseContext2);
|
|
665
|
+
await emitSdkResponseTelemetry(responseContext2);
|
|
482
666
|
if (willRetry) {
|
|
483
667
|
lastError = apiError;
|
|
484
668
|
await delay(
|
|
@@ -493,7 +677,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
493
677
|
throw apiError;
|
|
494
678
|
}
|
|
495
679
|
const successPayload = payload;
|
|
496
|
-
|
|
680
|
+
const responseContext = {
|
|
497
681
|
...hookRequestContext,
|
|
498
682
|
durationMs: Date.now() - startedAt,
|
|
499
683
|
status: response.status,
|
|
@@ -503,22 +687,25 @@ function createGatewayRequestClient(config = {}) {
|
|
|
503
687
|
idempotentReplay: successPayload.idempotentReplay,
|
|
504
688
|
retryAfterMs,
|
|
505
689
|
willRetry: false
|
|
506
|
-
}
|
|
690
|
+
};
|
|
691
|
+
await config.onResponse?.(responseContext);
|
|
692
|
+
await emitSdkResponseTelemetry(responseContext);
|
|
507
693
|
return successPayload;
|
|
508
694
|
} catch (fetchError) {
|
|
509
695
|
if (fetchError instanceof LucernApiError) {
|
|
510
696
|
throw fetchError;
|
|
511
697
|
}
|
|
512
|
-
const
|
|
513
|
-
const
|
|
514
|
-
await config.onResponse?.({
|
|
698
|
+
const willRetry = attempt < maxRetries && classifyGatewayErrorForRetry(fetchError);
|
|
699
|
+
const responseContext = {
|
|
515
700
|
...hookRequestContext,
|
|
516
701
|
durationMs: Date.now() - startedAt,
|
|
517
702
|
error: fetchError,
|
|
518
703
|
correlationId: requestId,
|
|
519
704
|
policyTraceId: null,
|
|
520
705
|
willRetry
|
|
521
|
-
}
|
|
706
|
+
};
|
|
707
|
+
await config.onResponse?.(responseContext);
|
|
708
|
+
await emitSdkResponseTelemetry(responseContext);
|
|
522
709
|
lastError = fetchError;
|
|
523
710
|
if (willRetry) {
|
|
524
711
|
await delay(computeRetryDelayMs({ attempt }));
|