@whittlelabs/sifter 0.4.0 → 0.4.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/bin.js +55 -31
- package/bin.js.map +2 -2
- package/package.json +1 -1
package/bin.js
CHANGED
|
@@ -15342,18 +15342,52 @@ var require_client = __commonJS({
|
|
|
15342
15342
|
var prompt_execution_1 = require_prompt_execution();
|
|
15343
15343
|
var JobsClient = class {
|
|
15344
15344
|
baseUrl;
|
|
15345
|
-
|
|
15345
|
+
apiKey;
|
|
15346
|
+
accessToken;
|
|
15347
|
+
getAccessToken;
|
|
15346
15348
|
onResponse;
|
|
15347
15349
|
constructor(config) {
|
|
15348
15350
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
15349
|
-
this.
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
} else if (config.accessToken) {
|
|
15353
|
-
this.headers["Authorization"] = `Bearer ${config.accessToken}`;
|
|
15354
|
-
}
|
|
15351
|
+
this.apiKey = config.apiKey;
|
|
15352
|
+
this.accessToken = config.accessToken;
|
|
15353
|
+
this.getAccessToken = config.getAccessToken;
|
|
15355
15354
|
this.onResponse = config.onResponse;
|
|
15356
15355
|
}
|
|
15356
|
+
/**
|
|
15357
|
+
* Headers for one request. The auth header is resolved per call so a
|
|
15358
|
+
* long-lived client picks up a refreshed token from `getAccessToken`
|
|
15359
|
+
* (the manager behind it re-mints before expiry) instead of pinning the
|
|
15360
|
+
* token it happened to hold at construction.
|
|
15361
|
+
*/
|
|
15362
|
+
async buildHeaders(forceRefresh = false) {
|
|
15363
|
+
const headers = { "Content-Type": "application/json" };
|
|
15364
|
+
if (this.apiKey) {
|
|
15365
|
+
headers["X-API-Key"] = this.apiKey;
|
|
15366
|
+
} else if (this.getAccessToken) {
|
|
15367
|
+
const token = await this.getAccessToken({ forceRefresh });
|
|
15368
|
+
if (token)
|
|
15369
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
15370
|
+
} else if (this.accessToken) {
|
|
15371
|
+
headers["Authorization"] = `Bearer ${this.accessToken}`;
|
|
15372
|
+
}
|
|
15373
|
+
return headers;
|
|
15374
|
+
}
|
|
15375
|
+
/**
|
|
15376
|
+
* Fetch with one auth retry. A 401 on a token-provider client usually means
|
|
15377
|
+
* the token was invalidated server-side (Keep restart, key rotation,
|
|
15378
|
+
* revoke-then-repair, clock skew) while the local expiry timer still thinks
|
|
15379
|
+
* it's valid. Force a re-mint and retry once before surfacing the failure.
|
|
15380
|
+
* `onResponse` (min-version contract) fires on the response we actually act
|
|
15381
|
+
* on. `body` is a string, so it is safe to resend.
|
|
15382
|
+
*/
|
|
15383
|
+
async fetchWithAuthRetry(method, url, body) {
|
|
15384
|
+
let response = await fetch(url, { method, headers: await this.buildHeaders(), body });
|
|
15385
|
+
if (response.status === 401 && this.getAccessToken) {
|
|
15386
|
+
response = await fetch(url, { method, headers: await this.buildHeaders(true), body });
|
|
15387
|
+
}
|
|
15388
|
+
this.onResponse?.(response);
|
|
15389
|
+
return response;
|
|
15390
|
+
}
|
|
15357
15391
|
// ── Attention Pools ──────────────────────────────────────────────
|
|
15358
15392
|
async createAttentionPool(options) {
|
|
15359
15393
|
return this.request("POST", "/api/attention-pools", options);
|
|
@@ -15543,22 +15577,9 @@ var require_client = __commonJS({
|
|
|
15543
15577
|
}
|
|
15544
15578
|
}
|
|
15545
15579
|
// ── HTTP plumbing ────────────────────────────────────────────────
|
|
15546
|
-
/** @internal exposed for the subscribe loop */
|
|
15547
|
-
buildUrl(path) {
|
|
15548
|
-
return `${this.baseUrl}${path}`;
|
|
15549
|
-
}
|
|
15550
|
-
/** @internal exposed for the subscribe loop */
|
|
15551
|
-
authHeaders() {
|
|
15552
|
-
return { ...this.headers };
|
|
15553
|
-
}
|
|
15554
15580
|
async request(method, path, body) {
|
|
15555
|
-
const url = this.
|
|
15556
|
-
const response = await
|
|
15557
|
-
method,
|
|
15558
|
-
headers: this.headers,
|
|
15559
|
-
body: body ? JSON.stringify(body) : void 0
|
|
15560
|
-
});
|
|
15561
|
-
this.onResponse?.(response);
|
|
15581
|
+
const url = `${this.baseUrl}${path}`;
|
|
15582
|
+
const response = await this.fetchWithAuthRetry(method, url, body ? JSON.stringify(body) : void 0);
|
|
15562
15583
|
const json = await response.json();
|
|
15563
15584
|
if (!response.ok || !json.success) {
|
|
15564
15585
|
const errorMessage = json.error?.message ?? `Request failed with status ${response.status}`;
|
|
@@ -15570,9 +15591,8 @@ var require_client = __commonJS({
|
|
|
15570
15591
|
return json.data;
|
|
15571
15592
|
}
|
|
15572
15593
|
async requestPaginated(method, path) {
|
|
15573
|
-
const url = this.
|
|
15574
|
-
const response = await
|
|
15575
|
-
this.onResponse?.(response);
|
|
15594
|
+
const url = `${this.baseUrl}${path}`;
|
|
15595
|
+
const response = await this.fetchWithAuthRetry(method, url);
|
|
15576
15596
|
const json = await response.json();
|
|
15577
15597
|
if (!response.ok || !json.success) {
|
|
15578
15598
|
const errorMessage = json.error?.message ?? `Request failed with status ${response.status}`;
|
|
@@ -16460,10 +16480,10 @@ var require_agent_token = __commonJS({
|
|
|
16460
16480
|
this.enabled = !!(config.clientId && config.clientSecret && config.keepApiUrl);
|
|
16461
16481
|
this.onResponse = config.onResponse;
|
|
16462
16482
|
}
|
|
16463
|
-
async getToken() {
|
|
16483
|
+
async getToken(forceRefresh = false) {
|
|
16464
16484
|
if (!this.enabled)
|
|
16465
16485
|
return null;
|
|
16466
|
-
if (this.token && Date.now() < this.expiresAt - 3e4) {
|
|
16486
|
+
if (!forceRefresh && this.token && Date.now() < this.expiresAt - 3e4) {
|
|
16467
16487
|
return this.token;
|
|
16468
16488
|
}
|
|
16469
16489
|
if (this.pendingExchange) {
|
|
@@ -17862,7 +17882,7 @@ var require_shuttle = __commonJS({
|
|
|
17862
17882
|
const jobsClient = new jobs_1.JobsClient({
|
|
17863
17883
|
baseUrl: this.config.auth.jobsApiUrl,
|
|
17864
17884
|
apiKey: auth.kind === "apiKey" ? auth.apiKey : void 0,
|
|
17865
|
-
|
|
17885
|
+
getAccessToken: auth.kind === "tokenProvider" ? auth.getToken : void 0,
|
|
17866
17886
|
onResponse: enforceMinVersion
|
|
17867
17887
|
});
|
|
17868
17888
|
const registry = new registry_1.ExecutorRegistry(this.brand.executorAllowlist);
|
|
@@ -17944,8 +17964,12 @@ var require_shuttle = __commonJS({
|
|
|
17944
17964
|
onResponse
|
|
17945
17965
|
});
|
|
17946
17966
|
const token = await tokens.getToken();
|
|
17947
|
-
if (token)
|
|
17948
|
-
return {
|
|
17967
|
+
if (token) {
|
|
17968
|
+
return {
|
|
17969
|
+
kind: "tokenProvider",
|
|
17970
|
+
getToken: (opts) => tokens.getToken(opts?.forceRefresh)
|
|
17971
|
+
};
|
|
17972
|
+
}
|
|
17949
17973
|
}
|
|
17950
17974
|
if (config.auth.apiKey) {
|
|
17951
17975
|
return { kind: "apiKey", apiKey: config.auth.apiKey };
|
|
@@ -18484,7 +18508,7 @@ var import_shuttle = __toESM(require_dist4());
|
|
|
18484
18508
|
// package.json
|
|
18485
18509
|
var package_default = {
|
|
18486
18510
|
name: "@whittlelabs/sifter",
|
|
18487
|
-
version: "0.4.
|
|
18511
|
+
version: "0.4.2",
|
|
18488
18512
|
description: "Whittle Sifter: paired AI reviewer for Whittle Sift attention pools.",
|
|
18489
18513
|
bin: {
|
|
18490
18514
|
"whittle-sifter": "./dist/bin.js"
|