risicare 0.3.0 → 0.4.0
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/README.md +26 -10
- package/dist/frameworks/instructor.cjs.map +1 -1
- package/dist/frameworks/instructor.js.map +1 -1
- package/dist/frameworks/langchain.cjs.map +1 -1
- package/dist/frameworks/langchain.js.map +1 -1
- package/dist/frameworks/langgraph.cjs.map +1 -1
- package/dist/frameworks/langgraph.js.map +1 -1
- package/dist/frameworks/llamaindex.cjs.map +1 -1
- package/dist/frameworks/llamaindex.js.map +1 -1
- package/dist/index.cjs +212 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +162 -6
- package/dist/index.d.ts +162 -6
- package/dist/index.js +209 -8
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic/index.cjs.map +1 -1
- package/dist/providers/anthropic/index.js.map +1 -1
- package/dist/providers/bedrock/index.cjs.map +1 -1
- package/dist/providers/bedrock/index.js.map +1 -1
- package/dist/providers/cerebras/index.cjs.map +1 -1
- package/dist/providers/cerebras/index.js.map +1 -1
- package/dist/providers/cohere/index.cjs.map +1 -1
- package/dist/providers/cohere/index.js.map +1 -1
- package/dist/providers/google/index.cjs.map +1 -1
- package/dist/providers/google/index.js.map +1 -1
- package/dist/providers/groq/index.cjs.map +1 -1
- package/dist/providers/groq/index.js.map +1 -1
- package/dist/providers/huggingface/index.cjs.map +1 -1
- package/dist/providers/huggingface/index.js.map +1 -1
- package/dist/providers/mistral/index.cjs.map +1 -1
- package/dist/providers/mistral/index.js.map +1 -1
- package/dist/providers/ollama/index.cjs.map +1 -1
- package/dist/providers/ollama/index.js.map +1 -1
- package/dist/providers/openai/index.cjs +16 -1327
- package/dist/providers/openai/index.cjs.map +1 -1
- package/dist/providers/openai/index.js +16 -1343
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/together/index.cjs.map +1 -1
- package/dist/providers/together/index.js.map +1 -1
- package/dist/providers/vercel-ai/index.cjs.map +1 -1
- package/dist/providers/vercel-ai/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1423,12 +1423,14 @@ var init_runtime = __esm({
|
|
|
1423
1423
|
var src_exports = {};
|
|
1424
1424
|
__export(src_exports, {
|
|
1425
1425
|
AgentRole: () => AgentRole,
|
|
1426
|
+
DEFAULT_TIMESTAMP_TOLERANCE_S: () => DEFAULT_TIMESTAMP_TOLERANCE_S,
|
|
1426
1427
|
MessageType: () => MessageType,
|
|
1427
1428
|
RisicareCallbackHandler: () => RisicareCallbackHandler,
|
|
1428
1429
|
RisicareLlamaIndexHandler: () => RisicareLlamaIndexHandler,
|
|
1429
1430
|
SemanticPhase: () => SemanticPhase,
|
|
1430
1431
|
SpanKind: () => SpanKind,
|
|
1431
1432
|
SpanStatus: () => SpanStatus,
|
|
1433
|
+
WebhookVerificationError: () => WebhookVerificationError,
|
|
1432
1434
|
agent: () => agent,
|
|
1433
1435
|
disable: () => disable,
|
|
1434
1436
|
enable: () => enable,
|
|
@@ -1472,6 +1474,7 @@ __export(src_exports, {
|
|
|
1472
1474
|
traceThink: () => traceThink,
|
|
1473
1475
|
tracedStream: () => tracedStream,
|
|
1474
1476
|
unregisterSpan: () => unregisterSpan,
|
|
1477
|
+
verifyWebhookSignature: () => verifyWebhookSignature,
|
|
1475
1478
|
withAgent: () => withAgent,
|
|
1476
1479
|
withPhase: () => withPhase,
|
|
1477
1480
|
withSession: () => withSession
|
|
@@ -2104,7 +2107,14 @@ var BatchSpanProcessor = class _BatchSpanProcessor {
|
|
|
2104
2107
|
failedExports = 0;
|
|
2105
2108
|
constructor(options) {
|
|
2106
2109
|
this._exporters = [...options.exporters];
|
|
2107
|
-
|
|
2110
|
+
const requestedBatchSize = options.batchSize ?? 100;
|
|
2111
|
+
const clampedBatchSize = Math.max(1, Math.min(requestedBatchSize, 1e4));
|
|
2112
|
+
if (clampedBatchSize !== requestedBatchSize) {
|
|
2113
|
+
warn(
|
|
2114
|
+
`batchSize=${requestedBatchSize} is outside the allowed range [1, 10000]; clamping to ${clampedBatchSize}`
|
|
2115
|
+
);
|
|
2116
|
+
}
|
|
2117
|
+
this._batchSize = clampedBatchSize;
|
|
2108
2118
|
this._batchTimeoutMs = options.batchTimeoutMs ?? 1e3;
|
|
2109
2119
|
this._maxQueueSize = options.maxQueueSize ?? 1e4;
|
|
2110
2120
|
this._debug = options.debug ?? false;
|
|
@@ -2245,11 +2255,15 @@ var HttpExporter = class {
|
|
|
2245
2255
|
_timeoutMs;
|
|
2246
2256
|
_maxRetries;
|
|
2247
2257
|
_compress;
|
|
2248
|
-
// Circuit breaker
|
|
2258
|
+
// Circuit breaker (CON-201 / B-16). Threshold and cooldown sized for
|
|
2259
|
+
// a "30-second prod restart" scenario: with default 1s batch flush a
|
|
2260
|
+
// 5-failure threshold opens the circuit ~5s into an outage and the 60s
|
|
2261
|
+
// cooldown gives the gateway time to come back before the half-open
|
|
2262
|
+
// probe fires. Lower numbers (was 3@30s) tripped on transient blips.
|
|
2249
2263
|
_consecutiveFailures = 0;
|
|
2250
2264
|
_circuitOpenUntil = 0;
|
|
2251
|
-
_circuitBreakerThreshold =
|
|
2252
|
-
_circuitBreakerCooldownMs =
|
|
2265
|
+
_circuitBreakerThreshold = 5;
|
|
2266
|
+
_circuitBreakerCooldownMs = 6e4;
|
|
2253
2267
|
constructor(options) {
|
|
2254
2268
|
this._endpoint = options.endpoint.replace(/\/+$/, "");
|
|
2255
2269
|
this._apiKey = options.apiKey;
|
|
@@ -2410,7 +2424,18 @@ var RisicareClient = class {
|
|
|
2410
2424
|
enabled: true,
|
|
2411
2425
|
debug: this.config.debug
|
|
2412
2426
|
});
|
|
2413
|
-
} catch {
|
|
2427
|
+
} catch (e) {
|
|
2428
|
+
const errName = e instanceof Error ? e.name : "Error";
|
|
2429
|
+
const errMsg = e instanceof Error ? e.message : String(e);
|
|
2430
|
+
try {
|
|
2431
|
+
console.warn(
|
|
2432
|
+
`[risicare] FixRuntime initialization failed \u2014 auto-fix is OFFLINE for this process. endpoint=${this.config.endpoint} error=${errName}: ${errMsg}. Tracing + reporting still work; only fix application is disabled. Pass debug:true in init() options for the full traceback.`
|
|
2433
|
+
);
|
|
2434
|
+
} catch {
|
|
2435
|
+
}
|
|
2436
|
+
if (this.config.debug) {
|
|
2437
|
+
debug(`FixRuntime init traceback: ${e instanceof Error && e.stack ? e.stack : String(e)}`);
|
|
2438
|
+
}
|
|
2414
2439
|
}
|
|
2415
2440
|
}
|
|
2416
2441
|
this._registerShutdownHooks();
|
|
@@ -2562,7 +2587,7 @@ function reportError(error, options) {
|
|
|
2562
2587
|
}
|
|
2563
2588
|
function score(traceId, name, value, options) {
|
|
2564
2589
|
try {
|
|
2565
|
-
if (typeof value !== "number" || value < 0 || value > 1) {
|
|
2590
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
|
|
2566
2591
|
debug(`score: value must be in [0.0, 1.0], got ${value}. Score not sent.`);
|
|
2567
2592
|
return;
|
|
2568
2593
|
}
|
|
@@ -2612,7 +2637,7 @@ function withAgent(options, fn) {
|
|
|
2612
2637
|
}
|
|
2613
2638
|
|
|
2614
2639
|
// src/decorators/agent.ts
|
|
2615
|
-
function
|
|
2640
|
+
function _wrapAgent(options, fn) {
|
|
2616
2641
|
const spanName = `agent:${options.name ?? "agent"}`;
|
|
2617
2642
|
return (...args) => {
|
|
2618
2643
|
const tracer = getTracer2();
|
|
@@ -2626,6 +2651,12 @@ function agent(options, fn) {
|
|
|
2626
2651
|
});
|
|
2627
2652
|
};
|
|
2628
2653
|
}
|
|
2654
|
+
function agent(options, fn) {
|
|
2655
|
+
if (fn === void 0) {
|
|
2656
|
+
return (realFn) => _wrapAgent(options, realFn);
|
|
2657
|
+
}
|
|
2658
|
+
return _wrapAgent(options, fn);
|
|
2659
|
+
}
|
|
2629
2660
|
|
|
2630
2661
|
// src/context/session.ts
|
|
2631
2662
|
function withSession(options, fn) {
|
|
@@ -2640,12 +2671,18 @@ function withSession(options, fn) {
|
|
|
2640
2671
|
}
|
|
2641
2672
|
|
|
2642
2673
|
// src/decorators/session.ts
|
|
2643
|
-
function
|
|
2674
|
+
function _wrapSession(optionsOrResolver, fn) {
|
|
2644
2675
|
return (...args) => {
|
|
2645
2676
|
const options = typeof optionsOrResolver === "function" ? optionsOrResolver(...args) : optionsOrResolver;
|
|
2646
2677
|
return withSession(options, () => fn(...args));
|
|
2647
2678
|
};
|
|
2648
2679
|
}
|
|
2680
|
+
function session(optionsOrResolver, fn) {
|
|
2681
|
+
if (fn === void 0) {
|
|
2682
|
+
return (realFn) => _wrapSession(optionsOrResolver, realFn);
|
|
2683
|
+
}
|
|
2684
|
+
return _wrapSession(optionsOrResolver, fn);
|
|
2685
|
+
}
|
|
2649
2686
|
|
|
2650
2687
|
// src/context/phase.ts
|
|
2651
2688
|
function withPhase(phase, fn) {
|
|
@@ -3267,15 +3304,181 @@ var RisicareLlamaIndexHandler = class {
|
|
|
3267
3304
|
|
|
3268
3305
|
// src/index.ts
|
|
3269
3306
|
init_runtime();
|
|
3307
|
+
|
|
3308
|
+
// src/webhooks.ts
|
|
3309
|
+
var import_node_crypto3 = require("crypto");
|
|
3310
|
+
var import_node_buffer = require("buffer");
|
|
3311
|
+
var DEFAULT_TIMESTAMP_TOLERANCE_S = 300;
|
|
3312
|
+
var SIGNATURE_HEADER = "X-Risicare-Signature";
|
|
3313
|
+
var TIMESTAMP_HEADER = "X-Risicare-Timestamp";
|
|
3314
|
+
var SUPPORTED_SCHEMES = ["v1"];
|
|
3315
|
+
var HEX_SHA256_RE = /^[0-9a-f]{64}$/;
|
|
3316
|
+
var WebhookVerificationError = class _WebhookVerificationError extends Error {
|
|
3317
|
+
constructor(message) {
|
|
3318
|
+
super(message);
|
|
3319
|
+
this.name = "WebhookVerificationError";
|
|
3320
|
+
Object.setPrototypeOf(this, _WebhookVerificationError.prototype);
|
|
3321
|
+
}
|
|
3322
|
+
};
|
|
3323
|
+
function getHeader(headers, name) {
|
|
3324
|
+
const lower = name.toLowerCase();
|
|
3325
|
+
if (typeof headers.get === "function") {
|
|
3326
|
+
const accessor = headers;
|
|
3327
|
+
const v = accessor.get(name) ?? accessor.get(lower);
|
|
3328
|
+
return v ?? void 0;
|
|
3329
|
+
}
|
|
3330
|
+
const dict = headers;
|
|
3331
|
+
const raw = dict[name] ?? dict[lower];
|
|
3332
|
+
if (raw === void 0) {
|
|
3333
|
+
return void 0;
|
|
3334
|
+
}
|
|
3335
|
+
if (Array.isArray(raw)) {
|
|
3336
|
+
return raw[0];
|
|
3337
|
+
}
|
|
3338
|
+
return raw;
|
|
3339
|
+
}
|
|
3340
|
+
function coercePayload(payload) {
|
|
3341
|
+
if (typeof payload === "string") {
|
|
3342
|
+
return import_node_buffer.Buffer.from(payload, "utf-8");
|
|
3343
|
+
}
|
|
3344
|
+
if (payload instanceof Uint8Array) {
|
|
3345
|
+
return import_node_buffer.Buffer.from(
|
|
3346
|
+
payload.buffer,
|
|
3347
|
+
payload.byteOffset,
|
|
3348
|
+
payload.byteLength
|
|
3349
|
+
);
|
|
3350
|
+
}
|
|
3351
|
+
if (payload instanceof ArrayBuffer) {
|
|
3352
|
+
return import_node_buffer.Buffer.from(payload);
|
|
3353
|
+
}
|
|
3354
|
+
throw new WebhookVerificationError(
|
|
3355
|
+
`payload must be Uint8Array, ArrayBuffer, Buffer, or string, got ${typeof payload}`
|
|
3356
|
+
);
|
|
3357
|
+
}
|
|
3358
|
+
function parseSignatureHeader(raw) {
|
|
3359
|
+
const parts = /* @__PURE__ */ Object.create(null);
|
|
3360
|
+
for (const rawSegment of raw.split(",")) {
|
|
3361
|
+
const segment = rawSegment.trim();
|
|
3362
|
+
if (segment === "") {
|
|
3363
|
+
continue;
|
|
3364
|
+
}
|
|
3365
|
+
const eqIdx = segment.indexOf("=");
|
|
3366
|
+
if (eqIdx === -1) {
|
|
3367
|
+
throw new WebhookVerificationError(
|
|
3368
|
+
`Malformed segment in ${SIGNATURE_HEADER}: ${JSON.stringify(segment)}`
|
|
3369
|
+
);
|
|
3370
|
+
}
|
|
3371
|
+
const key = segment.slice(0, eqIdx).trim();
|
|
3372
|
+
const value = segment.slice(eqIdx + 1).trim();
|
|
3373
|
+
parts[key] = value;
|
|
3374
|
+
}
|
|
3375
|
+
if (!("t" in parts)) {
|
|
3376
|
+
throw new WebhookVerificationError(
|
|
3377
|
+
`Missing \`t=\` (timestamp) in ${SIGNATURE_HEADER}`
|
|
3378
|
+
);
|
|
3379
|
+
}
|
|
3380
|
+
let scheme;
|
|
3381
|
+
for (const candidate of SUPPORTED_SCHEMES) {
|
|
3382
|
+
if (candidate in parts) {
|
|
3383
|
+
scheme = candidate;
|
|
3384
|
+
break;
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
if (scheme === void 0) {
|
|
3388
|
+
const keys = Object.keys(parts).sort();
|
|
3389
|
+
throw new WebhookVerificationError(
|
|
3390
|
+
`No supported signature scheme in ${SIGNATURE_HEADER}; expected one of (${SUPPORTED_SCHEMES.map((s) => `'${s}'`).join(", ")}), got keys [${keys.map((k) => `'${k}'`).join(", ")}]`
|
|
3391
|
+
);
|
|
3392
|
+
}
|
|
3393
|
+
const tRaw = parts["t"];
|
|
3394
|
+
if (!/^-?\d+$/.test(tRaw)) {
|
|
3395
|
+
throw new WebhookVerificationError(
|
|
3396
|
+
`Non-integer timestamp in ${SIGNATURE_HEADER}: ${JSON.stringify(tRaw)}`
|
|
3397
|
+
);
|
|
3398
|
+
}
|
|
3399
|
+
const ts = parseInt(tRaw, 10);
|
|
3400
|
+
if (!Number.isFinite(ts)) {
|
|
3401
|
+
throw new WebhookVerificationError(
|
|
3402
|
+
`Non-integer timestamp in ${SIGNATURE_HEADER}: ${JSON.stringify(tRaw)}`
|
|
3403
|
+
);
|
|
3404
|
+
}
|
|
3405
|
+
const sigHex = parts[scheme];
|
|
3406
|
+
if (sigHex === void 0 || sigHex === "") {
|
|
3407
|
+
throw new WebhookVerificationError(
|
|
3408
|
+
`Empty ${scheme}= value in ${SIGNATURE_HEADER}`
|
|
3409
|
+
);
|
|
3410
|
+
}
|
|
3411
|
+
return [ts, sigHex];
|
|
3412
|
+
}
|
|
3413
|
+
function safeHexEqual(computed, expected) {
|
|
3414
|
+
if (!HEX_SHA256_RE.test(expected)) {
|
|
3415
|
+
return false;
|
|
3416
|
+
}
|
|
3417
|
+
const a = import_node_buffer.Buffer.from(computed, "hex");
|
|
3418
|
+
const b = import_node_buffer.Buffer.from(expected, "hex");
|
|
3419
|
+
if (a.length !== b.length) {
|
|
3420
|
+
return false;
|
|
3421
|
+
}
|
|
3422
|
+
return (0, import_node_crypto3.timingSafeEqual)(a, b);
|
|
3423
|
+
}
|
|
3424
|
+
function verifyWebhookSignature(payload, headers, secret, opts = {}) {
|
|
3425
|
+
const toleranceS = opts.toleranceS ?? DEFAULT_TIMESTAMP_TOLERANCE_S;
|
|
3426
|
+
const payloadBytes = coercePayload(payload);
|
|
3427
|
+
const sigHeader = getHeader(headers, SIGNATURE_HEADER);
|
|
3428
|
+
if (sigHeader === void 0 || sigHeader === "") {
|
|
3429
|
+
throw new WebhookVerificationError(
|
|
3430
|
+
`Missing ${SIGNATURE_HEADER} header`
|
|
3431
|
+
);
|
|
3432
|
+
}
|
|
3433
|
+
const tsHeader = getHeader(headers, TIMESTAMP_HEADER);
|
|
3434
|
+
if (tsHeader === void 0 || tsHeader === "") {
|
|
3435
|
+
throw new WebhookVerificationError(
|
|
3436
|
+
`Missing ${TIMESTAMP_HEADER} header`
|
|
3437
|
+
);
|
|
3438
|
+
}
|
|
3439
|
+
const [tsInSig, expectedHex] = parseSignatureHeader(sigHeader);
|
|
3440
|
+
if (!/^-?\d+$/.test(tsHeader)) {
|
|
3441
|
+
throw new WebhookVerificationError(
|
|
3442
|
+
`Non-integer ${TIMESTAMP_HEADER}: ${JSON.stringify(tsHeader)}`
|
|
3443
|
+
);
|
|
3444
|
+
}
|
|
3445
|
+
const tsStandalone = parseInt(tsHeader, 10);
|
|
3446
|
+
if (!Number.isFinite(tsStandalone)) {
|
|
3447
|
+
throw new WebhookVerificationError(
|
|
3448
|
+
`Non-integer ${TIMESTAMP_HEADER}: ${JSON.stringify(tsHeader)}`
|
|
3449
|
+
);
|
|
3450
|
+
}
|
|
3451
|
+
if (tsStandalone !== tsInSig) {
|
|
3452
|
+
throw new WebhookVerificationError(
|
|
3453
|
+
`Timestamp mismatch: ${TIMESTAMP_HEADER}=${tsStandalone}, signature t=${tsInSig}`
|
|
3454
|
+
);
|
|
3455
|
+
}
|
|
3456
|
+
const now = opts._now !== void 0 ? Math.trunc(opts._now) : Math.floor(Date.now() / 1e3);
|
|
3457
|
+
const skew = Math.abs(now - tsInSig);
|
|
3458
|
+
if (skew > toleranceS) {
|
|
3459
|
+
throw new WebhookVerificationError(
|
|
3460
|
+
`Webhook timestamp outside tolerance: skew=${skew}s, max=${toleranceS}s`
|
|
3461
|
+
);
|
|
3462
|
+
}
|
|
3463
|
+
const hmac = (0, import_node_crypto3.createHmac)("sha256", secret);
|
|
3464
|
+
hmac.update(`${tsInSig}.`);
|
|
3465
|
+
hmac.update(payloadBytes);
|
|
3466
|
+
const computed = hmac.digest("hex");
|
|
3467
|
+
if (!safeHexEqual(computed, expectedHex)) {
|
|
3468
|
+
throw new WebhookVerificationError("Webhook signature mismatch");
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3270
3471
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3271
3472
|
0 && (module.exports = {
|
|
3272
3473
|
AgentRole,
|
|
3474
|
+
DEFAULT_TIMESTAMP_TOLERANCE_S,
|
|
3273
3475
|
MessageType,
|
|
3274
3476
|
RisicareCallbackHandler,
|
|
3275
3477
|
RisicareLlamaIndexHandler,
|
|
3276
3478
|
SemanticPhase,
|
|
3277
3479
|
SpanKind,
|
|
3278
3480
|
SpanStatus,
|
|
3481
|
+
WebhookVerificationError,
|
|
3279
3482
|
agent,
|
|
3280
3483
|
disable,
|
|
3281
3484
|
enable,
|
|
@@ -3319,6 +3522,7 @@ init_runtime();
|
|
|
3319
3522
|
traceThink,
|
|
3320
3523
|
tracedStream,
|
|
3321
3524
|
unregisterSpan,
|
|
3525
|
+
verifyWebhookSignature,
|
|
3322
3526
|
withAgent,
|
|
3323
3527
|
withPhase,
|
|
3324
3528
|
withSession
|