@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/dist/contextClient.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GatewayClientConfig, PlatformGatewaySuccess } from './coreClient.js';
|
|
2
2
|
import { PublicCompiledContext, CompileContextInput } from './contextTypes.js';
|
|
3
|
+
import '@lucern/transport-core';
|
|
3
4
|
import './authContext.js';
|
|
4
5
|
import './contracts/auth-session.contract.js';
|
|
5
6
|
import './types.js';
|
package/dist/contextClient.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/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
|
function fallbackErrorCode(status) {
|
|
221
343
|
if (status === 401) {
|
|
222
344
|
return "AUTHENTICATION_REQUIRED";
|
|
@@ -255,10 +377,8 @@ function computeRetryDelayMs(args) {
|
|
|
255
377
|
const jitterWindow = Math.max(250, Math.round(baseDelay * 0.25));
|
|
256
378
|
return baseDelay + Math.round(Math.random() * jitterWindow);
|
|
257
379
|
}
|
|
258
|
-
function
|
|
259
|
-
|
|
260
|
-
error.name = "AbortError";
|
|
261
|
-
return error;
|
|
380
|
+
function classifyGatewayErrorForRetry(error) {
|
|
381
|
+
return isGatewayRetryableError(error) || classifyRetry({ error }).retryable;
|
|
262
382
|
}
|
|
263
383
|
function isRecord(value) {
|
|
264
384
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -313,10 +433,18 @@ function cleanHeaderValue(value) {
|
|
|
313
433
|
return normalized ? normalized : void 0;
|
|
314
434
|
}
|
|
315
435
|
function createGatewayRequestClient(config = {}) {
|
|
316
|
-
const
|
|
317
|
-
const
|
|
318
|
-
const
|
|
319
|
-
const
|
|
436
|
+
const env = resolveEnvironment();
|
|
437
|
+
const runtime = createGatewayRuntime(config, env);
|
|
438
|
+
const baseUrl = resolveGatewayBaseUrl(config.baseUrl, env);
|
|
439
|
+
const maxRetries = runtime.profile.maxRetries;
|
|
440
|
+
const requestIdFactory = runtime.profile.requestIdFactory;
|
|
441
|
+
const requestTimeoutByMethod = runtime.profile.timeoutMsByMethod;
|
|
442
|
+
const defaultRequestTimeoutMs = runtime.profile.timeoutMs;
|
|
443
|
+
const normalizedEnvironment = normalizeGatewayEnvironment(config.environment);
|
|
444
|
+
const telemetryExporter = config.telemetryEnabled === false ? null : config.telemetryExporter ?? createTelemetryExporterFromEnv(telemetryEnvironmentRecord(env), {
|
|
445
|
+
service: "lucern-sdk",
|
|
446
|
+
environment: normalizedEnvironment
|
|
447
|
+
});
|
|
320
448
|
async function resolveAuthHeaders() {
|
|
321
449
|
const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
|
|
322
450
|
const headers = new Headers(provided);
|
|
@@ -328,7 +456,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
328
456
|
};
|
|
329
457
|
setIfAbsent("x-lucern-key", config.apiKey);
|
|
330
458
|
setIfAbsent("x-lucern-session-token", config.userToken);
|
|
331
|
-
setIfAbsent("x-lucern-environment",
|
|
459
|
+
setIfAbsent("x-lucern-environment", normalizedEnvironment);
|
|
332
460
|
setIfAbsent("x-lucern-clerk-id", config.clerkId);
|
|
333
461
|
setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
|
|
334
462
|
setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
|
|
@@ -343,19 +471,73 @@ function createGatewayRequestClient(config = {}) {
|
|
|
343
471
|
return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
|
|
344
472
|
}
|
|
345
473
|
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
474
|
+
const normalizeTransportError = (error, isTimeout) => {
|
|
475
|
+
if (isTimeout) {
|
|
476
|
+
return new GatewayTimeoutError(timeoutMs);
|
|
477
|
+
}
|
|
478
|
+
return error instanceof GatewayTimeoutError || error instanceof GatewayTransportError ? error : new GatewayTransportError(
|
|
479
|
+
error instanceof Error ? error.message : "Gateway transport error",
|
|
480
|
+
{
|
|
481
|
+
cause: error,
|
|
482
|
+
retryable: classifyGatewayErrorForRetry(error)
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
};
|
|
346
486
|
const controller = new AbortController();
|
|
347
487
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
488
|
+
const requestEffect = Effect.tryPromise({
|
|
489
|
+
try: () => runtime.fetch(url, { ...init, signal: controller.signal }),
|
|
490
|
+
catch: (error) => normalizeTransportError(error, controller.signal.aborted)
|
|
491
|
+
});
|
|
348
492
|
try {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
throw timeoutError(timeoutMs);
|
|
493
|
+
const exit = await Effect.runPromiseExit(requestEffect);
|
|
494
|
+
if (Exit.isSuccess(exit)) {
|
|
495
|
+
return exit.value;
|
|
353
496
|
}
|
|
354
|
-
|
|
497
|
+
const failure = Array.from(Cause.failures(exit.cause))[0];
|
|
498
|
+
if (failure !== void 0) {
|
|
499
|
+
throw failure;
|
|
500
|
+
}
|
|
501
|
+
throw Cause.squash(exit.cause);
|
|
355
502
|
} finally {
|
|
356
503
|
clearTimeout(timer);
|
|
357
504
|
}
|
|
358
505
|
}
|
|
506
|
+
async function emitSdkResponseTelemetry(context) {
|
|
507
|
+
const retry = classifyRetry({
|
|
508
|
+
status: context.status,
|
|
509
|
+
error: context.error,
|
|
510
|
+
retryAfter: context.retryAfterMs !== null && context.retryAfterMs !== void 0 ? String(context.retryAfterMs / 1e3) : void 0
|
|
511
|
+
});
|
|
512
|
+
await emitTelemetrySignal(telemetryExporter, {
|
|
513
|
+
signalType: "trace",
|
|
514
|
+
surface: "sdk-retry",
|
|
515
|
+
eventName: context.willRetry ? "sdk.retry" : context.error ? "sdk.request.error" : "sdk.request.complete",
|
|
516
|
+
severity: context.error ? context.willRetry ? "warn" : "error" : "info",
|
|
517
|
+
durationMs: context.durationMs,
|
|
518
|
+
metricName: "sdk.request.duration_ms",
|
|
519
|
+
metricValue: context.durationMs,
|
|
520
|
+
correlationId: context.correlationId ?? context.requestId,
|
|
521
|
+
policyTraceId: context.policyTraceId ?? null,
|
|
522
|
+
tenantId: context.headers.get("x-lucern-tenant-id") ?? context.headers.get("x-lucern-tenant") ?? void 0,
|
|
523
|
+
workspaceId: context.headers.get("x-lucern-workspace-id") ?? context.headers.get("x-lucern-workspace") ?? void 0,
|
|
524
|
+
attributes: {
|
|
525
|
+
service: "lucern-sdk",
|
|
526
|
+
operation: "gateway.request",
|
|
527
|
+
path: context.path,
|
|
528
|
+
httpMethod: context.method,
|
|
529
|
+
httpStatus: context.status,
|
|
530
|
+
attempt: context.attempt,
|
|
531
|
+
maxRetries: context.maxRetries,
|
|
532
|
+
retryReason: retry.reason,
|
|
533
|
+
retryAfterMs: context.retryAfterMs ?? retry.retryAfterMs,
|
|
534
|
+
willRetry: context.willRetry,
|
|
535
|
+
retryable: retry.retryable,
|
|
536
|
+
errorName: context.error instanceof Error ? context.error.name : void 0,
|
|
537
|
+
errorMessage: context.error instanceof Error ? context.error.message : void 0
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
}
|
|
359
541
|
async function parsePayload(response) {
|
|
360
542
|
const text = await response.text();
|
|
361
543
|
if (!text) {
|
|
@@ -371,11 +553,11 @@ function createGatewayRequestClient(config = {}) {
|
|
|
371
553
|
if (typeof requestTimeoutMs === "number") {
|
|
372
554
|
return requestTimeoutMs;
|
|
373
555
|
}
|
|
374
|
-
const methodTimeoutMs =
|
|
556
|
+
const methodTimeoutMs = requestTimeoutByMethod?.[method];
|
|
375
557
|
if (typeof methodTimeoutMs === "number") {
|
|
376
558
|
return methodTimeoutMs;
|
|
377
559
|
}
|
|
378
|
-
return
|
|
560
|
+
return defaultRequestTimeoutMs;
|
|
379
561
|
}
|
|
380
562
|
function tryParseGatewayEnvelopeJson(text) {
|
|
381
563
|
const trimmed = text.trim();
|
|
@@ -396,8 +578,8 @@ function createGatewayRequestClient(config = {}) {
|
|
|
396
578
|
const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
|
|
397
579
|
const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
|
|
398
580
|
const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
|
|
399
|
-
const details =
|
|
400
|
-
failure?.details ?? legacyError?.details
|
|
581
|
+
const details = runtime.redaction(
|
|
582
|
+
redactJsonDiagnosticValue(failure?.details ?? legacyError?.details)
|
|
401
583
|
);
|
|
402
584
|
const policySummary = readPolicySummaryFromDetails(details);
|
|
403
585
|
const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
|
|
@@ -467,7 +649,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
467
649
|
failure
|
|
468
650
|
});
|
|
469
651
|
const willRetry = attempt < maxRetries && retry.retryable;
|
|
470
|
-
|
|
652
|
+
const responseContext2 = {
|
|
471
653
|
...hookRequestContext,
|
|
472
654
|
durationMs: Date.now() - startedAt,
|
|
473
655
|
status: response.status,
|
|
@@ -477,7 +659,9 @@ function createGatewayRequestClient(config = {}) {
|
|
|
477
659
|
policyTraceId: apiError.policyTraceId ?? null,
|
|
478
660
|
retryAfterMs,
|
|
479
661
|
willRetry
|
|
480
|
-
}
|
|
662
|
+
};
|
|
663
|
+
await config.onResponse?.(responseContext2);
|
|
664
|
+
await emitSdkResponseTelemetry(responseContext2);
|
|
481
665
|
if (willRetry) {
|
|
482
666
|
lastError = apiError;
|
|
483
667
|
await delay(
|
|
@@ -492,7 +676,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
492
676
|
throw apiError;
|
|
493
677
|
}
|
|
494
678
|
const successPayload = payload;
|
|
495
|
-
|
|
679
|
+
const responseContext = {
|
|
496
680
|
...hookRequestContext,
|
|
497
681
|
durationMs: Date.now() - startedAt,
|
|
498
682
|
status: response.status,
|
|
@@ -502,22 +686,25 @@ function createGatewayRequestClient(config = {}) {
|
|
|
502
686
|
idempotentReplay: successPayload.idempotentReplay,
|
|
503
687
|
retryAfterMs,
|
|
504
688
|
willRetry: false
|
|
505
|
-
}
|
|
689
|
+
};
|
|
690
|
+
await config.onResponse?.(responseContext);
|
|
691
|
+
await emitSdkResponseTelemetry(responseContext);
|
|
506
692
|
return successPayload;
|
|
507
693
|
} catch (fetchError) {
|
|
508
694
|
if (fetchError instanceof LucernApiError) {
|
|
509
695
|
throw fetchError;
|
|
510
696
|
}
|
|
511
|
-
const
|
|
512
|
-
const
|
|
513
|
-
await config.onResponse?.({
|
|
697
|
+
const willRetry = attempt < maxRetries && classifyGatewayErrorForRetry(fetchError);
|
|
698
|
+
const responseContext = {
|
|
514
699
|
...hookRequestContext,
|
|
515
700
|
durationMs: Date.now() - startedAt,
|
|
516
701
|
error: fetchError,
|
|
517
702
|
correlationId: requestId,
|
|
518
703
|
policyTraceId: null,
|
|
519
704
|
willRetry
|
|
520
|
-
}
|
|
705
|
+
};
|
|
706
|
+
await config.onResponse?.(responseContext);
|
|
707
|
+
await emitSdkResponseTelemetry(responseContext);
|
|
521
708
|
lastError = fetchError;
|
|
522
709
|
if (willRetry) {
|
|
523
710
|
await delay(computeRetryDelayMs({ attempt }));
|