@highflame/sdk 0.3.3 → 0.3.5
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/dist/index.cjs +62 -4
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +69 -4
- package/package.json +10 -1
package/dist/index.cjs
CHANGED
|
@@ -148,8 +148,53 @@ async function* streamSseResponse(response) {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// src/telemetry.ts
|
|
152
|
+
var _otelApi;
|
|
153
|
+
function getOtelApi() {
|
|
154
|
+
if (_otelApi !== void 0) return _otelApi;
|
|
155
|
+
try {
|
|
156
|
+
_otelApi = require("@opentelemetry/api");
|
|
157
|
+
} catch {
|
|
158
|
+
_otelApi = null;
|
|
159
|
+
}
|
|
160
|
+
return _otelApi;
|
|
161
|
+
}
|
|
162
|
+
function injectTraceContext(headers) {
|
|
163
|
+
const api = getOtelApi();
|
|
164
|
+
if (!api) return;
|
|
165
|
+
const propagator = api.propagation;
|
|
166
|
+
const context = api.context.active();
|
|
167
|
+
propagator.inject(context, headers, {
|
|
168
|
+
set(carrier, key, value) {
|
|
169
|
+
carrier[key] = value;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async function withSpan(name, attributes, fn) {
|
|
174
|
+
const api = getOtelApi();
|
|
175
|
+
if (!api) return fn();
|
|
176
|
+
const tracer = api.trace.getTracer("@highflame/sdk", VERSION);
|
|
177
|
+
const parentContext = api.context.active();
|
|
178
|
+
const span = tracer.startSpan(name, { attributes }, parentContext);
|
|
179
|
+
const spanContext = api.trace.setSpan(parentContext, span);
|
|
180
|
+
try {
|
|
181
|
+
const result = await api.context.with(spanContext, fn);
|
|
182
|
+
span.setStatus({ code: api.SpanStatusCode.OK });
|
|
183
|
+
return result;
|
|
184
|
+
} catch (err) {
|
|
185
|
+
span.setStatus({
|
|
186
|
+
code: api.SpanStatusCode.ERROR,
|
|
187
|
+
message: err instanceof Error ? err.message : String(err)
|
|
188
|
+
});
|
|
189
|
+
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
190
|
+
throw err;
|
|
191
|
+
} finally {
|
|
192
|
+
span.end();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
151
196
|
// src/client.ts
|
|
152
|
-
var VERSION = "0.
|
|
197
|
+
var VERSION = "0.3.4";
|
|
153
198
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
154
199
|
var DEFAULT_MAX_RETRIES = 2;
|
|
155
200
|
var RETRY_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
@@ -201,7 +246,14 @@ var GuardResource = class {
|
|
|
201
246
|
}
|
|
202
247
|
/** Evaluate content against guard policies (POST /v1/guard). */
|
|
203
248
|
async evaluate(request, options) {
|
|
204
|
-
return
|
|
249
|
+
return withSpan(
|
|
250
|
+
"highflame.guard",
|
|
251
|
+
{
|
|
252
|
+
"highflame.action": request.action ?? "process_prompt",
|
|
253
|
+
"highflame.content_type": request.content_type ?? "prompt"
|
|
254
|
+
},
|
|
255
|
+
() => this._client._postJSON("/v1/guard", request, options?.timeout)
|
|
256
|
+
);
|
|
205
257
|
}
|
|
206
258
|
/** Shorthand: evaluate a user prompt. */
|
|
207
259
|
async evaluatePrompt(content, options) {
|
|
@@ -236,7 +288,11 @@ var DetectResource = class {
|
|
|
236
288
|
}
|
|
237
289
|
/** Run detectors without policy evaluation (POST /v1/detect). */
|
|
238
290
|
async run(request, options) {
|
|
239
|
-
return
|
|
291
|
+
return withSpan(
|
|
292
|
+
"highflame.detect",
|
|
293
|
+
{ "highflame.content_type": request.content_type ?? "prompt" },
|
|
294
|
+
() => this._client._postJSON("/v1/detect", request, options?.timeout)
|
|
295
|
+
);
|
|
240
296
|
}
|
|
241
297
|
};
|
|
242
298
|
var DetectorsResource = class {
|
|
@@ -281,7 +337,7 @@ var Highflame = class {
|
|
|
281
337
|
const baseUrl = options.baseUrl ?? SAAS_BASE_URL;
|
|
282
338
|
const tokenUrl = options.tokenUrl ?? SAAS_TOKEN_URL;
|
|
283
339
|
this.#baseUrl = baseUrl.replace(/\/$/, "");
|
|
284
|
-
this.#tokenUrl = options.apiKey.startsWith("hf_sk") ? tokenUrl : void 0;
|
|
340
|
+
this.#tokenUrl = options.apiKey.startsWith("hf_sk") || options.apiKey.startsWith("hfa_") ? tokenUrl : void 0;
|
|
285
341
|
this.#apiKey = options.apiKey;
|
|
286
342
|
this.#timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
287
343
|
this.#maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
@@ -407,6 +463,7 @@ var Highflame = class {
|
|
|
407
463
|
this.#log.debug("Request body: %s", truncate(init.body));
|
|
408
464
|
}
|
|
409
465
|
const authHeaders = await this.getAuthHeaders();
|
|
466
|
+
injectTraceContext(authHeaders);
|
|
410
467
|
if (idempotencyKey) {
|
|
411
468
|
authHeaders["X-Idempotency-Key"] = idempotencyKey;
|
|
412
469
|
}
|
|
@@ -468,6 +525,7 @@ var Highflame = class {
|
|
|
468
525
|
const effectiveTimeout = overrideTimeout ?? this.#timeout;
|
|
469
526
|
this.#log.debug("POST %s (stream)", path);
|
|
470
527
|
const authHeaders = await this.getAuthHeaders();
|
|
528
|
+
injectTraceContext(authHeaders);
|
|
471
529
|
const controller = new AbortController();
|
|
472
530
|
const timer = setTimeout(() => controller.abort(), effectiveTimeout);
|
|
473
531
|
let response;
|
package/dist/index.d.cts
CHANGED
|
@@ -506,8 +506,8 @@ interface ProblemDetails {
|
|
|
506
506
|
interface StreamEvent {
|
|
507
507
|
/** Event payload (DetectorResult for detector_result, GuardResponse for decision). */
|
|
508
508
|
data: Record<string, unknown>;
|
|
509
|
-
/** Event type: detector_result (per-detector), decision (final), or
|
|
510
|
-
type: "detector_result" | "decision" | "error";
|
|
509
|
+
/** Event type: detector_result (per-detector), decision (final), error, or message (keepalive/info). */
|
|
510
|
+
type: "detector_result" | "decision" | "error" | "message";
|
|
511
511
|
}
|
|
512
512
|
/** Response from the token exchange endpoint (used by SDK auth). */
|
|
513
513
|
interface TokenResponse {
|
|
@@ -553,7 +553,7 @@ interface TokenResponse {
|
|
|
553
553
|
*/
|
|
554
554
|
|
|
555
555
|
/** SDK version — kept in sync with package.json via `make version-sync`. */
|
|
556
|
-
declare const VERSION = "0.
|
|
556
|
+
declare const VERSION = "0.3.4";
|
|
557
557
|
/**
|
|
558
558
|
* Pluggable logger interface.
|
|
559
559
|
*
|
|
@@ -568,11 +568,11 @@ interface Logger {
|
|
|
568
568
|
warn(message: string, ...args: unknown[]): void;
|
|
569
569
|
}
|
|
570
570
|
interface HighflameOptions {
|
|
571
|
-
/** Service API key (`hf_sk_...`) or a raw JWT. */
|
|
571
|
+
/** Service API key (`hf_sk_...`), agent API key (`hfa_...`), or a raw JWT. */
|
|
572
572
|
apiKey: string;
|
|
573
573
|
/** Base URL of the guard service. Defaults to Highflame SaaS. */
|
|
574
574
|
baseUrl?: string;
|
|
575
|
-
/** Token exchange URL. Defaults to Highflame SaaS.
|
|
575
|
+
/** Token exchange URL. Defaults to Highflame SaaS. Used for `hf_sk_*` and `hfa_*` keys. */
|
|
576
576
|
tokenUrl?: string;
|
|
577
577
|
/** Request timeout in milliseconds. Default: 30000. */
|
|
578
578
|
timeout?: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -506,8 +506,8 @@ interface ProblemDetails {
|
|
|
506
506
|
interface StreamEvent {
|
|
507
507
|
/** Event payload (DetectorResult for detector_result, GuardResponse for decision). */
|
|
508
508
|
data: Record<string, unknown>;
|
|
509
|
-
/** Event type: detector_result (per-detector), decision (final), or
|
|
510
|
-
type: "detector_result" | "decision" | "error";
|
|
509
|
+
/** Event type: detector_result (per-detector), decision (final), error, or message (keepalive/info). */
|
|
510
|
+
type: "detector_result" | "decision" | "error" | "message";
|
|
511
511
|
}
|
|
512
512
|
/** Response from the token exchange endpoint (used by SDK auth). */
|
|
513
513
|
interface TokenResponse {
|
|
@@ -553,7 +553,7 @@ interface TokenResponse {
|
|
|
553
553
|
*/
|
|
554
554
|
|
|
555
555
|
/** SDK version — kept in sync with package.json via `make version-sync`. */
|
|
556
|
-
declare const VERSION = "0.
|
|
556
|
+
declare const VERSION = "0.3.4";
|
|
557
557
|
/**
|
|
558
558
|
* Pluggable logger interface.
|
|
559
559
|
*
|
|
@@ -568,11 +568,11 @@ interface Logger {
|
|
|
568
568
|
warn(message: string, ...args: unknown[]): void;
|
|
569
569
|
}
|
|
570
570
|
interface HighflameOptions {
|
|
571
|
-
/** Service API key (`hf_sk_...`) or a raw JWT. */
|
|
571
|
+
/** Service API key (`hf_sk_...`), agent API key (`hfa_...`), or a raw JWT. */
|
|
572
572
|
apiKey: string;
|
|
573
573
|
/** Base URL of the guard service. Defaults to Highflame SaaS. */
|
|
574
574
|
baseUrl?: string;
|
|
575
|
-
/** Token exchange URL. Defaults to Highflame SaaS.
|
|
575
|
+
/** Token exchange URL. Defaults to Highflame SaaS. Used for `hf_sk_*` and `hfa_*` keys. */
|
|
576
576
|
tokenUrl?: string;
|
|
577
577
|
/** Request timeout in milliseconds. Default: 30000. */
|
|
578
578
|
timeout?: number;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/errors.ts
|
|
2
9
|
var HighflameError = class extends Error {
|
|
3
10
|
constructor(message) {
|
|
@@ -110,8 +117,53 @@ async function* streamSseResponse(response) {
|
|
|
110
117
|
}
|
|
111
118
|
}
|
|
112
119
|
|
|
120
|
+
// src/telemetry.ts
|
|
121
|
+
var _otelApi;
|
|
122
|
+
function getOtelApi() {
|
|
123
|
+
if (_otelApi !== void 0) return _otelApi;
|
|
124
|
+
try {
|
|
125
|
+
_otelApi = __require("@opentelemetry/api");
|
|
126
|
+
} catch {
|
|
127
|
+
_otelApi = null;
|
|
128
|
+
}
|
|
129
|
+
return _otelApi;
|
|
130
|
+
}
|
|
131
|
+
function injectTraceContext(headers) {
|
|
132
|
+
const api = getOtelApi();
|
|
133
|
+
if (!api) return;
|
|
134
|
+
const propagator = api.propagation;
|
|
135
|
+
const context = api.context.active();
|
|
136
|
+
propagator.inject(context, headers, {
|
|
137
|
+
set(carrier, key, value) {
|
|
138
|
+
carrier[key] = value;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async function withSpan(name, attributes, fn) {
|
|
143
|
+
const api = getOtelApi();
|
|
144
|
+
if (!api) return fn();
|
|
145
|
+
const tracer = api.trace.getTracer("@highflame/sdk", VERSION);
|
|
146
|
+
const parentContext = api.context.active();
|
|
147
|
+
const span = tracer.startSpan(name, { attributes }, parentContext);
|
|
148
|
+
const spanContext = api.trace.setSpan(parentContext, span);
|
|
149
|
+
try {
|
|
150
|
+
const result = await api.context.with(spanContext, fn);
|
|
151
|
+
span.setStatus({ code: api.SpanStatusCode.OK });
|
|
152
|
+
return result;
|
|
153
|
+
} catch (err) {
|
|
154
|
+
span.setStatus({
|
|
155
|
+
code: api.SpanStatusCode.ERROR,
|
|
156
|
+
message: err instanceof Error ? err.message : String(err)
|
|
157
|
+
});
|
|
158
|
+
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
159
|
+
throw err;
|
|
160
|
+
} finally {
|
|
161
|
+
span.end();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
113
165
|
// src/client.ts
|
|
114
|
-
var VERSION = "0.
|
|
166
|
+
var VERSION = "0.3.4";
|
|
115
167
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
116
168
|
var DEFAULT_MAX_RETRIES = 2;
|
|
117
169
|
var RETRY_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
@@ -163,7 +215,14 @@ var GuardResource = class {
|
|
|
163
215
|
}
|
|
164
216
|
/** Evaluate content against guard policies (POST /v1/guard). */
|
|
165
217
|
async evaluate(request, options) {
|
|
166
|
-
return
|
|
218
|
+
return withSpan(
|
|
219
|
+
"highflame.guard",
|
|
220
|
+
{
|
|
221
|
+
"highflame.action": request.action ?? "process_prompt",
|
|
222
|
+
"highflame.content_type": request.content_type ?? "prompt"
|
|
223
|
+
},
|
|
224
|
+
() => this._client._postJSON("/v1/guard", request, options?.timeout)
|
|
225
|
+
);
|
|
167
226
|
}
|
|
168
227
|
/** Shorthand: evaluate a user prompt. */
|
|
169
228
|
async evaluatePrompt(content, options) {
|
|
@@ -198,7 +257,11 @@ var DetectResource = class {
|
|
|
198
257
|
}
|
|
199
258
|
/** Run detectors without policy evaluation (POST /v1/detect). */
|
|
200
259
|
async run(request, options) {
|
|
201
|
-
return
|
|
260
|
+
return withSpan(
|
|
261
|
+
"highflame.detect",
|
|
262
|
+
{ "highflame.content_type": request.content_type ?? "prompt" },
|
|
263
|
+
() => this._client._postJSON("/v1/detect", request, options?.timeout)
|
|
264
|
+
);
|
|
202
265
|
}
|
|
203
266
|
};
|
|
204
267
|
var DetectorsResource = class {
|
|
@@ -243,7 +306,7 @@ var Highflame = class {
|
|
|
243
306
|
const baseUrl = options.baseUrl ?? SAAS_BASE_URL;
|
|
244
307
|
const tokenUrl = options.tokenUrl ?? SAAS_TOKEN_URL;
|
|
245
308
|
this.#baseUrl = baseUrl.replace(/\/$/, "");
|
|
246
|
-
this.#tokenUrl = options.apiKey.startsWith("hf_sk") ? tokenUrl : void 0;
|
|
309
|
+
this.#tokenUrl = options.apiKey.startsWith("hf_sk") || options.apiKey.startsWith("hfa_") ? tokenUrl : void 0;
|
|
247
310
|
this.#apiKey = options.apiKey;
|
|
248
311
|
this.#timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
249
312
|
this.#maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
@@ -369,6 +432,7 @@ var Highflame = class {
|
|
|
369
432
|
this.#log.debug("Request body: %s", truncate(init.body));
|
|
370
433
|
}
|
|
371
434
|
const authHeaders = await this.getAuthHeaders();
|
|
435
|
+
injectTraceContext(authHeaders);
|
|
372
436
|
if (idempotencyKey) {
|
|
373
437
|
authHeaders["X-Idempotency-Key"] = idempotencyKey;
|
|
374
438
|
}
|
|
@@ -430,6 +494,7 @@ var Highflame = class {
|
|
|
430
494
|
const effectiveTimeout = overrideTimeout ?? this.#timeout;
|
|
431
495
|
this.#log.debug("POST %s (stream)", path);
|
|
432
496
|
const authHeaders = await this.getAuthHeaders();
|
|
497
|
+
injectTraceContext(authHeaders);
|
|
433
498
|
const controller = new AbortController();
|
|
434
499
|
const timer = setTimeout(() => controller.abort(), effectiveTimeout);
|
|
435
500
|
let response;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highflame/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "JavaScript/TypeScript SDK for Highflame AI guardrails",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"coverage": "vitest run --coverage"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
+
"@opentelemetry/api": "^1.9.0",
|
|
33
34
|
"@types/node": "^20",
|
|
34
35
|
"@vitest/coverage-v8": "^2",
|
|
35
36
|
"eslint": "^9",
|
|
@@ -40,6 +41,14 @@
|
|
|
40
41
|
"typescript-eslint": "^8",
|
|
41
42
|
"vitest": "^2"
|
|
42
43
|
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@opentelemetry/api": "^1.4.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"@opentelemetry/api": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
43
52
|
"engines": {
|
|
44
53
|
"node": ">=18"
|
|
45
54
|
}
|