@lucern/sdk 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -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/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,6 +1,7 @@
|
|
|
1
1
|
import { GatewayClientConfig, PlatformGatewaySuccess } from './coreClient.js';
|
|
2
2
|
import { JsonObject, ListResult } from './types.js';
|
|
3
3
|
import { GraphIntelligenceQueryMode, GraphIntelligenceQueryWithTools } from '@lucern/contracts';
|
|
4
|
+
import '@lucern/transport-core';
|
|
4
5
|
import './authContext.js';
|
|
5
6
|
import './contracts/auth-session.contract.js';
|
|
6
7
|
import './contracts/workflow-runtime.contract.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;
|
|
@@ -237,6 +266,99 @@ function generatePortableRequestId() {
|
|
|
237
266
|
8
|
|
238
267
|
).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
239
268
|
}
|
|
269
|
+
function resolveEnvironment() {
|
|
270
|
+
const processEnv = typeof globalThis === "object" && globalThis !== null && "process" in globalThis ? globalThis.process : void 0;
|
|
271
|
+
const env = processEnv !== void 0 && typeof processEnv === "object" && processEnv !== null && typeof processEnv.env === "object" ? processEnv.env : void 0;
|
|
272
|
+
return {
|
|
273
|
+
get: (name) => {
|
|
274
|
+
const value = env?.[name];
|
|
275
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function telemetryEnvironmentRecord(environment) {
|
|
280
|
+
const names = [
|
|
281
|
+
"LUCERN_TELEMETRY_ENABLED",
|
|
282
|
+
"AXIOM_TELEMETRY_ENABLED",
|
|
283
|
+
"LUCERN_AXIOM_TOKEN",
|
|
284
|
+
"AXIOM_TOKEN",
|
|
285
|
+
"LUCERN_AXIOM_EVENTS_DATASET",
|
|
286
|
+
"LUCERN_AXIOM_DATASET",
|
|
287
|
+
"AXIOM_EVENTS_DATASET",
|
|
288
|
+
"AXIOM_DATASET",
|
|
289
|
+
"LUCERN_AXIOM_API_URL",
|
|
290
|
+
"AXIOM_URL",
|
|
291
|
+
"LUCERN_ENVIRONMENT",
|
|
292
|
+
"NODE_ENV",
|
|
293
|
+
"LUCERN_RELEASE",
|
|
294
|
+
"SENTRY_RELEASE",
|
|
295
|
+
"VERCEL_GIT_COMMIT_SHA"
|
|
296
|
+
];
|
|
297
|
+
return Object.fromEntries(
|
|
298
|
+
names.map((name) => [name, environment.get(name)])
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
function resolveRequestProfile(config, environment) {
|
|
302
|
+
const requestIdFactory = config.requestIdFactory ?? (() => generatePortableRequestId());
|
|
303
|
+
const parsedMaxRetries = parseIntegerFromString(
|
|
304
|
+
config.maxRetries,
|
|
305
|
+
environment.get(DEFAULT_ENV_MAX_RETRIES)
|
|
306
|
+
);
|
|
307
|
+
const parsedTimeoutMs = parseIntegerFromString(
|
|
308
|
+
config.timeoutMs,
|
|
309
|
+
environment.get(DEFAULT_ENV_TIMEOUT_MS)
|
|
310
|
+
);
|
|
311
|
+
const methodTimeouts = {
|
|
312
|
+
...config.timeoutMsByMethod
|
|
313
|
+
};
|
|
314
|
+
for (const method of ["GET", "POST", "PUT", "PATCH", "DELETE"]) {
|
|
315
|
+
const envKey = `${ENV_TIMEOUT_BY_METHOD_PREFIX}${method}`;
|
|
316
|
+
const raw = environment.get(envKey);
|
|
317
|
+
if (!raw || methodTimeouts[method] !== void 0) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
const parsed = parseIntegerFromString(void 0, raw);
|
|
321
|
+
if (typeof parsed === "number") {
|
|
322
|
+
methodTimeouts[method] = parsed;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
maxRetries: parsedMaxRetries ?? DEFAULT_GATEWAY_MAX_RETRIES,
|
|
327
|
+
timeoutMs: parsedTimeoutMs ?? DEFAULT_GATEWAY_TIMEOUT_MS,
|
|
328
|
+
timeoutMsByMethod: methodTimeouts,
|
|
329
|
+
requestIdFactory
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function createGatewayRuntime(config, environment) {
|
|
333
|
+
return {
|
|
334
|
+
fetch: config.fetchImpl ?? fetch,
|
|
335
|
+
now: () => Date.now(),
|
|
336
|
+
sleep: (ms) => delay(ms),
|
|
337
|
+
env: environment,
|
|
338
|
+
redaction: resolveRequestRedactionValue,
|
|
339
|
+
profile: resolveRequestProfile(config, environment)
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
function parseIntegerFromString(value, rawValue) {
|
|
343
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
|
|
344
|
+
return value;
|
|
345
|
+
}
|
|
346
|
+
if (typeof rawValue !== "string" || !rawValue.trim()) {
|
|
347
|
+
return void 0;
|
|
348
|
+
}
|
|
349
|
+
const parsed = Number.parseInt(rawValue, 10);
|
|
350
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
351
|
+
}
|
|
352
|
+
function resolveRequestRedactionValue(value) {
|
|
353
|
+
return redactDiagnosticValue(value);
|
|
354
|
+
}
|
|
355
|
+
function resolveGatewayBaseUrl(configBaseUrl, environment) {
|
|
356
|
+
const envBaseUrl = environment.get("LUCERN_API_URL") ?? environment.get("LUCERN_BASE_URL") ?? environment.get("LUCERN_GATEWAY_BASE_URL");
|
|
357
|
+
return (configBaseUrl ?? envBaseUrl ?? "").replace(/\/+$/, "");
|
|
358
|
+
}
|
|
359
|
+
function normalizeGatewayEnvironment(value) {
|
|
360
|
+
return value === "sandbox" || value === "production" ? value : void 0;
|
|
361
|
+
}
|
|
240
362
|
var randomIdempotencyKey = generatePortableRequestId;
|
|
241
363
|
function fallbackErrorCode(status) {
|
|
242
364
|
if (status === 401) {
|
|
@@ -276,10 +398,8 @@ function computeRetryDelayMs(args) {
|
|
|
276
398
|
const jitterWindow = Math.max(250, Math.round(baseDelay * 0.25));
|
|
277
399
|
return baseDelay + Math.round(Math.random() * jitterWindow);
|
|
278
400
|
}
|
|
279
|
-
function
|
|
280
|
-
|
|
281
|
-
error.name = "AbortError";
|
|
282
|
-
return error;
|
|
401
|
+
function classifyGatewayErrorForRetry(error) {
|
|
402
|
+
return isGatewayRetryableError(error) || classifyRetry({ error }).retryable;
|
|
283
403
|
}
|
|
284
404
|
function isRecord(value) {
|
|
285
405
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -334,10 +454,18 @@ function cleanHeaderValue(value) {
|
|
|
334
454
|
return normalized ? normalized : void 0;
|
|
335
455
|
}
|
|
336
456
|
function createGatewayRequestClient(config = {}) {
|
|
337
|
-
const
|
|
338
|
-
const
|
|
339
|
-
const
|
|
340
|
-
const
|
|
457
|
+
const env = resolveEnvironment();
|
|
458
|
+
const runtime = createGatewayRuntime(config, env);
|
|
459
|
+
const baseUrl = resolveGatewayBaseUrl(config.baseUrl, env);
|
|
460
|
+
const maxRetries = runtime.profile.maxRetries;
|
|
461
|
+
const requestIdFactory = runtime.profile.requestIdFactory;
|
|
462
|
+
const requestTimeoutByMethod = runtime.profile.timeoutMsByMethod;
|
|
463
|
+
const defaultRequestTimeoutMs = runtime.profile.timeoutMs;
|
|
464
|
+
const normalizedEnvironment = normalizeGatewayEnvironment(config.environment);
|
|
465
|
+
const telemetryExporter = config.telemetryEnabled === false ? null : config.telemetryExporter ?? createTelemetryExporterFromEnv(telemetryEnvironmentRecord(env), {
|
|
466
|
+
service: "lucern-sdk",
|
|
467
|
+
environment: normalizedEnvironment
|
|
468
|
+
});
|
|
341
469
|
async function resolveAuthHeaders() {
|
|
342
470
|
const provided = config.getAuthHeaders ? await config.getAuthHeaders() : {};
|
|
343
471
|
const headers = new Headers(provided);
|
|
@@ -349,7 +477,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
349
477
|
};
|
|
350
478
|
setIfAbsent("x-lucern-key", config.apiKey);
|
|
351
479
|
setIfAbsent("x-lucern-session-token", config.userToken);
|
|
352
|
-
setIfAbsent("x-lucern-environment",
|
|
480
|
+
setIfAbsent("x-lucern-environment", normalizedEnvironment);
|
|
353
481
|
setIfAbsent("x-lucern-clerk-id", config.clerkId);
|
|
354
482
|
setIfAbsent("x-lucern-user-id", config.userId ?? config.clerkId);
|
|
355
483
|
setIfAbsent("x-lucern-deployment-host", config.deploymentHost);
|
|
@@ -364,19 +492,73 @@ function createGatewayRequestClient(config = {}) {
|
|
|
364
492
|
return mergeHeaderRecord(base, createCanonicalAuthHeaders(authContext));
|
|
365
493
|
}
|
|
366
494
|
async function fetchWithTimeout(url, init, timeoutMs) {
|
|
495
|
+
const normalizeTransportError = (error, isTimeout) => {
|
|
496
|
+
if (isTimeout) {
|
|
497
|
+
return new GatewayTimeoutError(timeoutMs);
|
|
498
|
+
}
|
|
499
|
+
return error instanceof GatewayTimeoutError || error instanceof GatewayTransportError ? error : new GatewayTransportError(
|
|
500
|
+
error instanceof Error ? error.message : "Gateway transport error",
|
|
501
|
+
{
|
|
502
|
+
cause: error,
|
|
503
|
+
retryable: classifyGatewayErrorForRetry(error)
|
|
504
|
+
}
|
|
505
|
+
);
|
|
506
|
+
};
|
|
367
507
|
const controller = new AbortController();
|
|
368
508
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
509
|
+
const requestEffect = Effect.tryPromise({
|
|
510
|
+
try: () => runtime.fetch(url, { ...init, signal: controller.signal }),
|
|
511
|
+
catch: (error) => normalizeTransportError(error, controller.signal.aborted)
|
|
512
|
+
});
|
|
369
513
|
try {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
throw timeoutError(timeoutMs);
|
|
514
|
+
const exit = await Effect.runPromiseExit(requestEffect);
|
|
515
|
+
if (Exit.isSuccess(exit)) {
|
|
516
|
+
return exit.value;
|
|
374
517
|
}
|
|
375
|
-
|
|
518
|
+
const failure = Array.from(Cause.failures(exit.cause))[0];
|
|
519
|
+
if (failure !== void 0) {
|
|
520
|
+
throw failure;
|
|
521
|
+
}
|
|
522
|
+
throw Cause.squash(exit.cause);
|
|
376
523
|
} finally {
|
|
377
524
|
clearTimeout(timer);
|
|
378
525
|
}
|
|
379
526
|
}
|
|
527
|
+
async function emitSdkResponseTelemetry(context) {
|
|
528
|
+
const retry = classifyRetry({
|
|
529
|
+
status: context.status,
|
|
530
|
+
error: context.error,
|
|
531
|
+
retryAfter: context.retryAfterMs !== null && context.retryAfterMs !== void 0 ? String(context.retryAfterMs / 1e3) : void 0
|
|
532
|
+
});
|
|
533
|
+
await emitTelemetrySignal(telemetryExporter, {
|
|
534
|
+
signalType: "trace",
|
|
535
|
+
surface: "sdk-retry",
|
|
536
|
+
eventName: context.willRetry ? "sdk.retry" : context.error ? "sdk.request.error" : "sdk.request.complete",
|
|
537
|
+
severity: context.error ? context.willRetry ? "warn" : "error" : "info",
|
|
538
|
+
durationMs: context.durationMs,
|
|
539
|
+
metricName: "sdk.request.duration_ms",
|
|
540
|
+
metricValue: context.durationMs,
|
|
541
|
+
correlationId: context.correlationId ?? context.requestId,
|
|
542
|
+
policyTraceId: context.policyTraceId ?? null,
|
|
543
|
+
tenantId: context.headers.get("x-lucern-tenant-id") ?? context.headers.get("x-lucern-tenant") ?? void 0,
|
|
544
|
+
workspaceId: context.headers.get("x-lucern-workspace-id") ?? context.headers.get("x-lucern-workspace") ?? void 0,
|
|
545
|
+
attributes: {
|
|
546
|
+
service: "lucern-sdk",
|
|
547
|
+
operation: "gateway.request",
|
|
548
|
+
path: context.path,
|
|
549
|
+
httpMethod: context.method,
|
|
550
|
+
httpStatus: context.status,
|
|
551
|
+
attempt: context.attempt,
|
|
552
|
+
maxRetries: context.maxRetries,
|
|
553
|
+
retryReason: retry.reason,
|
|
554
|
+
retryAfterMs: context.retryAfterMs ?? retry.retryAfterMs,
|
|
555
|
+
willRetry: context.willRetry,
|
|
556
|
+
retryable: retry.retryable,
|
|
557
|
+
errorName: context.error instanceof Error ? context.error.name : void 0,
|
|
558
|
+
errorMessage: context.error instanceof Error ? context.error.message : void 0
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
}
|
|
380
562
|
async function parsePayload(response) {
|
|
381
563
|
const text = await response.text();
|
|
382
564
|
if (!text) {
|
|
@@ -392,11 +574,11 @@ function createGatewayRequestClient(config = {}) {
|
|
|
392
574
|
if (typeof requestTimeoutMs === "number") {
|
|
393
575
|
return requestTimeoutMs;
|
|
394
576
|
}
|
|
395
|
-
const methodTimeoutMs =
|
|
577
|
+
const methodTimeoutMs = requestTimeoutByMethod?.[method];
|
|
396
578
|
if (typeof methodTimeoutMs === "number") {
|
|
397
579
|
return methodTimeoutMs;
|
|
398
580
|
}
|
|
399
|
-
return
|
|
581
|
+
return defaultRequestTimeoutMs;
|
|
400
582
|
}
|
|
401
583
|
function tryParseGatewayEnvelopeJson(text) {
|
|
402
584
|
const trimmed = text.trim();
|
|
@@ -417,8 +599,8 @@ function createGatewayRequestClient(config = {}) {
|
|
|
417
599
|
const legacyError = failure && isRecord(failure.error) ? failure.error : failure?.legacyError;
|
|
418
600
|
const correlationId = failure?.correlationId ?? args.response.headers.get("x-lucern-correlation-id")?.trim() ?? args.requestId;
|
|
419
601
|
const policyTraceId = failure?.policyTraceId ?? args.response.headers.get("x-lucern-policy-trace-id")?.trim() ?? null;
|
|
420
|
-
const details =
|
|
421
|
-
failure?.details ?? legacyError?.details
|
|
602
|
+
const details = runtime.redaction(
|
|
603
|
+
redactJsonDiagnosticValue(failure?.details ?? legacyError?.details)
|
|
422
604
|
);
|
|
423
605
|
const policySummary = readPolicySummaryFromDetails(details);
|
|
424
606
|
const failureMessage = typeof failure?.error === "string" ? failure.error : legacyError?.message;
|
|
@@ -488,7 +670,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
488
670
|
failure
|
|
489
671
|
});
|
|
490
672
|
const willRetry = attempt < maxRetries && retry.retryable;
|
|
491
|
-
|
|
673
|
+
const responseContext2 = {
|
|
492
674
|
...hookRequestContext,
|
|
493
675
|
durationMs: Date.now() - startedAt,
|
|
494
676
|
status: response.status,
|
|
@@ -498,7 +680,9 @@ function createGatewayRequestClient(config = {}) {
|
|
|
498
680
|
policyTraceId: apiError.policyTraceId ?? null,
|
|
499
681
|
retryAfterMs,
|
|
500
682
|
willRetry
|
|
501
|
-
}
|
|
683
|
+
};
|
|
684
|
+
await config.onResponse?.(responseContext2);
|
|
685
|
+
await emitSdkResponseTelemetry(responseContext2);
|
|
502
686
|
if (willRetry) {
|
|
503
687
|
lastError = apiError;
|
|
504
688
|
await delay(
|
|
@@ -513,7 +697,7 @@ function createGatewayRequestClient(config = {}) {
|
|
|
513
697
|
throw apiError;
|
|
514
698
|
}
|
|
515
699
|
const successPayload = payload;
|
|
516
|
-
|
|
700
|
+
const responseContext = {
|
|
517
701
|
...hookRequestContext,
|
|
518
702
|
durationMs: Date.now() - startedAt,
|
|
519
703
|
status: response.status,
|
|
@@ -523,22 +707,25 @@ function createGatewayRequestClient(config = {}) {
|
|
|
523
707
|
idempotentReplay: successPayload.idempotentReplay,
|
|
524
708
|
retryAfterMs,
|
|
525
709
|
willRetry: false
|
|
526
|
-
}
|
|
710
|
+
};
|
|
711
|
+
await config.onResponse?.(responseContext);
|
|
712
|
+
await emitSdkResponseTelemetry(responseContext);
|
|
527
713
|
return successPayload;
|
|
528
714
|
} catch (fetchError) {
|
|
529
715
|
if (fetchError instanceof LucernApiError) {
|
|
530
716
|
throw fetchError;
|
|
531
717
|
}
|
|
532
|
-
const
|
|
533
|
-
const
|
|
534
|
-
await config.onResponse?.({
|
|
718
|
+
const willRetry = attempt < maxRetries && classifyGatewayErrorForRetry(fetchError);
|
|
719
|
+
const responseContext = {
|
|
535
720
|
...hookRequestContext,
|
|
536
721
|
durationMs: Date.now() - startedAt,
|
|
537
722
|
error: fetchError,
|
|
538
723
|
correlationId: requestId,
|
|
539
724
|
policyTraceId: null,
|
|
540
725
|
willRetry
|
|
541
|
-
}
|
|
726
|
+
};
|
|
727
|
+
await config.onResponse?.(responseContext);
|
|
728
|
+
await emitSdkResponseTelemetry(responseContext);
|
|
542
729
|
lastError = fetchError;
|
|
543
730
|
if (willRetry) {
|
|
544
731
|
await delay(computeRetryDelayMs({ attempt }));
|