@hue-run/sdk 0.11.1 → 0.11.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/CLI.md +81 -39
- package/README.md +4 -2
- package/dist/cli/eval.d.ts +4 -0
- package/dist/cli/eval.js +16 -11
- package/dist/cli/listen.d.ts +1 -1
- package/dist/cli/listen.js +54 -12
- package/dist/cli/mcp.d.ts +18 -7
- package/dist/cli/mcp.js +347 -65
- package/dist/evals/checkpoint.d.ts +5 -0
- package/dist/evals/checkpoint.js +17 -1
- package/dist/evals/client.d.ts +11 -5
- package/dist/evals/client.js +29 -12
- package/dist/evals/files.js +18 -10
- package/dist/evals/local-worker.js +9 -5
- package/dist/evals/simulation.js +7 -5
- package/dist/provider-tools.d.ts +3 -1
- package/dist/provider-tools.js +4 -2
- package/dist/tool-definitions.d.ts +14 -3
- package/dist/tool-definitions.js +635 -53
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/** A server- or user-provided identifier that is safe as a single checkpoint path component:
|
|
2
|
+
* no separators, no `.`/`..`, and it stays directly inside the directory it is joined onto. */
|
|
3
|
+
export declare function checkpointSegment(value: string, label: string): string;
|
|
4
|
+
/** `join(directory, ...segments)` after validating every segment. */
|
|
5
|
+
export declare function checkpointPath(directory: string, ...segments: [string, string][]): string;
|
|
1
6
|
/** The checkpoint belongs to a run started with a different identity. When only its content
|
|
2
7
|
* policy differs, `startedWith` holds the policy the unfinished run was started with. */
|
|
3
8
|
export declare class CheckpointIdentityError extends Error {
|
package/dist/evals/checkpoint.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import { constants, rmSync } from "node:fs";
|
|
2
2
|
import { lstat, mkdir, open, rename, rm } from "node:fs/promises";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
3
|
+
import { join, resolve, sep } from "node:path";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { onForcedExit } from "./exit-cleanup.js";
|
|
6
6
|
import { digest } from "./json.js";
|
|
7
7
|
const CONTENT_POLICY = ["persistResultContent", "captureContent"];
|
|
8
|
+
const SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
9
|
+
/** A server- or user-provided identifier that is safe as a single checkpoint path component:
|
|
10
|
+
* no separators, no `.`/`..`, and it stays directly inside the directory it is joined onto. */
|
|
11
|
+
export function checkpointSegment(value, label) {
|
|
12
|
+
if (typeof value !== "string" || !SEGMENT.test(value))
|
|
13
|
+
throw new Error(`Refusing to use ${label} ${JSON.stringify(value)} in a checkpoint path`);
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
/** `join(directory, ...segments)` after validating every segment. */
|
|
17
|
+
export function checkpointPath(directory, ...segments) {
|
|
18
|
+
const root = resolve(directory);
|
|
19
|
+
const path = resolve(root, ...segments.map(([value, label]) => checkpointSegment(value, label)));
|
|
20
|
+
if (path !== root && !path.startsWith(root.endsWith(sep) ? root : root + sep))
|
|
21
|
+
throw new Error("Checkpoint path escapes its directory");
|
|
22
|
+
return path;
|
|
23
|
+
}
|
|
8
24
|
/** The checkpoint belongs to a run started with a different identity. When only its content
|
|
9
25
|
* policy differs, `startedWith` holds the policy the unfinished run was started with. */
|
|
10
26
|
export class CheckpointIdentityError extends Error {
|
package/dist/evals/client.d.ts
CHANGED
|
@@ -44,7 +44,8 @@ export declare class EvaluationClient {
|
|
|
44
44
|
private readonly timeoutMillis;
|
|
45
45
|
constructor(options: EvaluationClientOptions);
|
|
46
46
|
/** Sends one request to Hue, again after the wait while Hue refuses it with a short
|
|
47
|
-
* `Retry-After`. `init` runs for every attempt, so each has its own timeout
|
|
47
|
+
* `Retry-After`. `init` runs for every attempt, so each has its own timeout; `signal` also ends
|
|
48
|
+
* each attempt, and a wait to send one again, whose refusal is then the caller's error. */
|
|
48
49
|
private send;
|
|
49
50
|
private request;
|
|
50
51
|
/** Verified bytes of one ready artifact in this project, bounded to the 25 MiB pilot file size.
|
|
@@ -170,8 +171,10 @@ export declare class EvaluationClient {
|
|
|
170
171
|
revokeAttemptConnection(input: {
|
|
171
172
|
bindingId: string;
|
|
172
173
|
}): Promise<import("./attempt.js").RevokeAttemptResult>;
|
|
173
|
-
/** Reads one artifact reservation and its verification state. */
|
|
174
|
-
getArtifact(id: string
|
|
174
|
+
/** Reads one artifact reservation and its verification state. `signal` ends the request. */
|
|
175
|
+
getArtifact(id: string, options?: {
|
|
176
|
+
signal?: AbortSignal;
|
|
177
|
+
}): Promise<ArtifactReservation>;
|
|
175
178
|
/** Reserves an artifact by declared identity; replaying the key returns the same reservation. */
|
|
176
179
|
reserveArtifact(input: {
|
|
177
180
|
/** Stable key; replaying it returns the same reservation. */
|
|
@@ -187,8 +190,11 @@ export declare class EvaluationClient {
|
|
|
187
190
|
}): Promise<ArtifactReservation>;
|
|
188
191
|
/** Issues a short-lived storage capability for staging the reserved artifact's bytes. */
|
|
189
192
|
requestArtifactUpload(id: string): Promise<ArtifactUpload>;
|
|
190
|
-
/** Asks Hue to verify the staged bytes against the declared identity.
|
|
191
|
-
|
|
193
|
+
/** Asks Hue to verify the staged bytes against the declared identity. `signal` ends the
|
|
194
|
+
* request, and a wait to send it again. */
|
|
195
|
+
completeArtifact(id: string, options?: {
|
|
196
|
+
signal?: AbortSignal;
|
|
197
|
+
}): Promise<ArtifactReservation>;
|
|
192
198
|
/** Saves an execution's outcome and creates its immutable subject. */
|
|
193
199
|
completeExecution(id: string, input: CompleteExecution): Promise<Completion>;
|
|
194
200
|
/** Marks an experiment finished. */
|
package/dist/evals/client.js
CHANGED
|
@@ -149,12 +149,15 @@ export class EvaluationClient {
|
|
|
149
149
|
this.timeoutMillis = validated.timeoutMillis;
|
|
150
150
|
}
|
|
151
151
|
/** Sends one request to Hue, again after the wait while Hue refuses it with a short
|
|
152
|
-
* `Retry-After`. `init` runs for every attempt, so each has its own timeout
|
|
153
|
-
|
|
152
|
+
* `Retry-After`. `init` runs for every attempt, so each has its own timeout; `signal` also ends
|
|
153
|
+
* each attempt, and a wait to send one again, whose refusal is then the caller's error. */
|
|
154
|
+
async send(url, init, signal) {
|
|
154
155
|
for (let attempt = 0;; attempt++) {
|
|
155
156
|
let response;
|
|
156
157
|
try {
|
|
157
|
-
|
|
158
|
+
const attemptInit = init();
|
|
159
|
+
const signals = [attemptInit.signal, signal].filter((item) => !!item);
|
|
160
|
+
response = await fetch(url, { ...attemptInit, signal: AbortSignal.any(signals) });
|
|
158
161
|
}
|
|
159
162
|
catch {
|
|
160
163
|
throw new HueApiError();
|
|
@@ -164,10 +167,23 @@ export class EvaluationClient {
|
|
|
164
167
|
return response;
|
|
165
168
|
await response.body?.cancel().catch(() => undefined);
|
|
166
169
|
// Never sooner than asked; the jitter spreads out parallel requests refused together.
|
|
167
|
-
await new Promise((resolve) =>
|
|
170
|
+
await new Promise((resolve) => {
|
|
171
|
+
const done = () => {
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
signal?.removeEventListener("abort", done);
|
|
174
|
+
resolve();
|
|
175
|
+
};
|
|
176
|
+
const timer = setTimeout(done, seconds * 1000 * (1 + Math.random() * 0.5));
|
|
177
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
178
|
+
// The signal may have ended while the refusal's body was cancelled.
|
|
179
|
+
if (signal?.aborted)
|
|
180
|
+
done();
|
|
181
|
+
});
|
|
182
|
+
if (signal?.aborted)
|
|
183
|
+
throw new HueApiError(response.status, askedRetryAfter(response));
|
|
168
184
|
}
|
|
169
185
|
}
|
|
170
|
-
async request(method, path, body, bounds = { ...valueBounds, bytes: 1024 * 1024 }) {
|
|
186
|
+
async request(method, path, body, bounds = { ...valueBounds, bytes: 1024 * 1024 }, signal) {
|
|
171
187
|
// Optional top-level fields are omitted intentionally; nested undefined remains invalid.
|
|
172
188
|
const payload = body === undefined
|
|
173
189
|
? undefined
|
|
@@ -181,7 +197,7 @@ export class EvaluationClient {
|
|
|
181
197
|
body: payload,
|
|
182
198
|
redirect: "error",
|
|
183
199
|
signal: AbortSignal.timeout(this.timeoutMillis),
|
|
184
|
-
}));
|
|
200
|
+
}), signal);
|
|
185
201
|
if (!response.ok) {
|
|
186
202
|
await response.body?.cancel();
|
|
187
203
|
throw new HueApiError(response.status, askedRetryAfter(response));
|
|
@@ -503,9 +519,9 @@ export class EvaluationClient {
|
|
|
503
519
|
throw new HueApiError();
|
|
504
520
|
}
|
|
505
521
|
}
|
|
506
|
-
/** Reads one artifact reservation and its verification state. */
|
|
507
|
-
getArtifact(id) {
|
|
508
|
-
return this.request("GET", `/artifacts/${uuid(id)}
|
|
522
|
+
/** Reads one artifact reservation and its verification state. `signal` ends the request. */
|
|
523
|
+
getArtifact(id, options = {}) {
|
|
524
|
+
return this.request("GET", `/artifacts/${uuid(id)}`, undefined, undefined, options.signal);
|
|
509
525
|
}
|
|
510
526
|
/** Reserves an artifact by declared identity; replaying the key returns the same reservation. */
|
|
511
527
|
reserveArtifact(input) {
|
|
@@ -515,9 +531,10 @@ export class EvaluationClient {
|
|
|
515
531
|
requestArtifactUpload(id) {
|
|
516
532
|
return this.request("POST", `/artifacts/${uuid(id)}/upload`, {});
|
|
517
533
|
}
|
|
518
|
-
/** Asks Hue to verify the staged bytes against the declared identity.
|
|
519
|
-
|
|
520
|
-
|
|
534
|
+
/** Asks Hue to verify the staged bytes against the declared identity. `signal` ends the
|
|
535
|
+
* request, and a wait to send it again. */
|
|
536
|
+
completeArtifact(id, options = {}) {
|
|
537
|
+
return this.request("POST", `/artifacts/${uuid(id)}/complete`, {}, undefined, options.signal);
|
|
521
538
|
}
|
|
522
539
|
/** Saves an execution's outcome and creates its immutable subject. */
|
|
523
540
|
completeExecution(id, input) {
|
package/dist/evals/files.js
CHANGED
|
@@ -339,21 +339,33 @@ function mayStillVerify(error) {
|
|
|
339
339
|
* a pause: ready is returned; verifying is completed again, which Hue refuses while its lease
|
|
340
340
|
* holds and restarts once it lapsed; an artifact a retryable refusal (a lost response, 429 or 503)
|
|
341
341
|
* left unverified is completed again up to three times; any other state is returned for the
|
|
342
|
-
* caller to refuse (a resume uploads a rejected artifact again). All within `timing.settleMillis
|
|
342
|
+
* caller to refuse (a resume uploads a rejected artifact again). All within `timing.settleMillis`,
|
|
343
|
+
* which also ends a request in flight and the client's own wait to send one again.
|
|
343
344
|
*/
|
|
344
345
|
async function settleArtifact(client, id, timing) {
|
|
345
346
|
const deadline = Date.now() + timing.settleMillis;
|
|
347
|
+
const signal = AbortSignal.timeout(timing.settleMillis);
|
|
348
|
+
// The last state read, which names the state when the deadline cuts off a request at it.
|
|
349
|
+
let known;
|
|
350
|
+
const timedOut = (last) => {
|
|
351
|
+
const seconds = Math.round(timing.settleMillis / 1000);
|
|
352
|
+
return new Error(last?.state === "verifying"
|
|
353
|
+
? `Hue was still verifying generated file ${id} after ${seconds} seconds`
|
|
354
|
+
: `Hue had not verified generated file ${id} after ${seconds} seconds (${last ? `it was ${last.state}` : "its state could not be read"})`);
|
|
355
|
+
};
|
|
346
356
|
let pause = timing.pollMillis;
|
|
347
357
|
let retries = 0;
|
|
348
358
|
for (;;) {
|
|
349
359
|
let refusedForNow;
|
|
350
360
|
let asked = 0;
|
|
351
361
|
try {
|
|
352
|
-
return (await client.completeArtifact(id)).state;
|
|
362
|
+
return (await client.completeArtifact(id, { signal })).state;
|
|
353
363
|
}
|
|
354
364
|
catch (error) {
|
|
355
|
-
if (!mayStillVerify(error)
|
|
365
|
+
if (!mayStillVerify(error))
|
|
356
366
|
throw error;
|
|
367
|
+
if (Date.now() >= deadline)
|
|
368
|
+
throw timedOut(known);
|
|
357
369
|
refusedForNow = error.status !== 409;
|
|
358
370
|
// A refusal that says how long to wait is waited out, within the settling window.
|
|
359
371
|
asked = (error.retryAfterSeconds ?? 0) * 1000;
|
|
@@ -362,7 +374,7 @@ async function settleArtifact(client, id, timing) {
|
|
|
362
374
|
pause = Math.min(pause * 2, timing.maxPollMillis);
|
|
363
375
|
let current;
|
|
364
376
|
try {
|
|
365
|
-
current = await client.getArtifact(id);
|
|
377
|
+
current = known = await client.getArtifact(id, { signal });
|
|
366
378
|
}
|
|
367
379
|
catch (error) {
|
|
368
380
|
if (!mayStillVerify(error))
|
|
@@ -375,12 +387,8 @@ async function settleArtifact(client, id, timing) {
|
|
|
375
387
|
current.failureCode !== "mismatch";
|
|
376
388
|
if (current && current.state !== "verifying" && !(unverified && refusedForNow && retries++ < 3))
|
|
377
389
|
return current.state;
|
|
378
|
-
if (Date.now() >= deadline)
|
|
379
|
-
|
|
380
|
-
throw new Error(current?.state === "verifying"
|
|
381
|
-
? `Hue was still verifying generated file ${id} after ${seconds} seconds`
|
|
382
|
-
: `Hue had not verified generated file ${id} after ${seconds} seconds (${current ? `it was ${current.state}` : "its state could not be read"})`);
|
|
383
|
-
}
|
|
390
|
+
if (Date.now() >= deadline)
|
|
391
|
+
throw timedOut(current ?? known);
|
|
384
392
|
}
|
|
385
393
|
}
|
|
386
394
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { CheckpointStore } from "./checkpoint.js";
|
|
3
|
+
import { CheckpointStore, checkpointPath, checkpointSegment } from "./checkpoint.js";
|
|
4
4
|
import { pinRequestedAttemptV2, requestedAttemptV2, runEnvironmentTarget, } from "./environment-target.js";
|
|
5
5
|
import { runExperiment, OutcomeSerializationError, TargetOutcomeUncertainError, UncertainExecutionError, } from "./runner.js";
|
|
6
6
|
/** Capability strings a registration declares; Hue offers only matching cases. */
|
|
@@ -159,14 +159,18 @@ export async function runLocalAgent(options) {
|
|
|
159
159
|
}, Math.min(15_000, Math.max(1_000, interval)));
|
|
160
160
|
let experimentFinished = false;
|
|
161
161
|
try {
|
|
162
|
+
const experimentId = checkpointSegment(claim.experimentId, "experiment id");
|
|
162
163
|
const requested = requestedConfiguration
|
|
163
|
-
? pinRequestedAttemptV2(requestedConfiguration, (await options.client.getExperiment(
|
|
164
|
+
? pinRequestedAttemptV2(requestedConfiguration, (await options.client.getExperiment(experimentId)).config)
|
|
164
165
|
: undefined;
|
|
165
166
|
const report = await runExperiment({
|
|
166
167
|
client: options.client,
|
|
167
168
|
hue: options.hue,
|
|
168
|
-
experimentId
|
|
169
|
-
checkpointDirectory:
|
|
169
|
+
experimentId,
|
|
170
|
+
checkpointDirectory: checkpointPath(directory, [
|
|
171
|
+
`experiment-${experimentId}`,
|
|
172
|
+
"experiment id",
|
|
173
|
+
]),
|
|
170
174
|
persistResultContent: true,
|
|
171
175
|
// Worker dispatch uses the case pin: directTarget never receives a world.
|
|
172
176
|
environmentEvidence: options.directTarget ? "when_pinned" : "required",
|
package/dist/evals/simulation.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { join } from "node:path";
|
|
3
2
|
import { HueEnvironmentError } from "../environment/client.js";
|
|
4
3
|
import { HueApiError } from "./client.js";
|
|
5
|
-
import { CheckpointStore } from "./checkpoint.js";
|
|
4
|
+
import { CheckpointStore, checkpointPath, checkpointSegment } from "./checkpoint.js";
|
|
6
5
|
import { MAX_ENVIRONMENT_STEPS } from "./environment-evidence.js";
|
|
7
6
|
import { aggregateBounds, digest, json } from "./json.js";
|
|
8
7
|
import { normalizeScorerDefinitionForPublication } from "./scorer-publication.js";
|
|
@@ -404,7 +403,7 @@ export async function runSimulation(options) {
|
|
|
404
403
|
let bindings = options.localScorers ?? [];
|
|
405
404
|
if (!attempt.experimentId) {
|
|
406
405
|
const resolved = await resolveExperiment(options, definition, attempt.idempotencyKey);
|
|
407
|
-
attempt.experimentId = resolved.experimentId;
|
|
406
|
+
attempt.experimentId = checkpointSegment(resolved.experimentId, "experiment id");
|
|
408
407
|
bindings = resolved.bindings;
|
|
409
408
|
attempt.stage = "running";
|
|
410
409
|
await store.write("active-attempt", attempt);
|
|
@@ -417,7 +416,7 @@ export async function runSimulation(options) {
|
|
|
417
416
|
...(options.localScorers ?? []),
|
|
418
417
|
];
|
|
419
418
|
}
|
|
420
|
-
const experimentId = attempt.experimentId;
|
|
419
|
+
const experimentId = checkpointSegment(attempt.experimentId, "experiment id");
|
|
421
420
|
const runUrl = new URL(`/experiments/${experimentId}`, options.client.baseUrl).toString();
|
|
422
421
|
await options.onProgress?.({ type: "run_created", experimentId, runUrl });
|
|
423
422
|
const requested = requestedConfiguration
|
|
@@ -427,7 +426,10 @@ export async function runSimulation(options) {
|
|
|
427
426
|
client: options.client,
|
|
428
427
|
hue: options.hue,
|
|
429
428
|
experimentId,
|
|
430
|
-
checkpointDirectory:
|
|
429
|
+
checkpointDirectory: checkpointPath(store.directory, [
|
|
430
|
+
`experiment-${experimentId}`,
|
|
431
|
+
"experiment id",
|
|
432
|
+
]),
|
|
431
433
|
persistResultContent: options.persistResultContent,
|
|
432
434
|
traceEvidence: options.traceEvidence,
|
|
433
435
|
...(options.traceNotAccepted ? { traceNotAccepted: options.traceNotAccepted } : {}),
|
package/dist/provider-tools.d.ts
CHANGED
|
@@ -31,7 +31,9 @@ export interface HostedToolActivity {
|
|
|
31
31
|
/**
|
|
32
32
|
* A provider's error text as a failed call exports it under content capture: credentials
|
|
33
33
|
* scrubbed first, then at most 1,024 code points with `…` marking a cut, lone surrogates
|
|
34
|
-
* replaced and NUL removed.
|
|
34
|
+
* replaced and NUL removed. Only the first 16,384 code points are scrubbed, and what that cut
|
|
35
|
+
* interrupts (a quoted value, a URL, a prefixed token) is redacted to it. The Python SDK
|
|
36
|
+
* produces the same text.
|
|
35
37
|
*/
|
|
36
38
|
export declare function providerErrorDescription(value: string): string;
|
|
37
39
|
/**
|
package/dist/provider-tools.js
CHANGED
|
@@ -74,11 +74,13 @@ function codePoints(text, count) {
|
|
|
74
74
|
/**
|
|
75
75
|
* A provider's error text as a failed call exports it under content capture: credentials
|
|
76
76
|
* scrubbed first, then at most 1,024 code points with `…` marking a cut, lone surrogates
|
|
77
|
-
* replaced and NUL removed.
|
|
77
|
+
* replaced and NUL removed. Only the first 16,384 code points are scrubbed, and what that cut
|
|
78
|
+
* interrupts (a quoted value, a URL, a prefixed token) is redacted to it. The Python SDK
|
|
79
|
+
* produces the same text.
|
|
78
80
|
*/
|
|
79
81
|
export function providerErrorDescription(value) {
|
|
80
82
|
const scanned = codePoints(value.toWellFormed().replaceAll("\u0000", ""), MAX_ERROR_SCAN);
|
|
81
|
-
const bounded = codePoints(scrubCredentialText(scanned.text), MAX_ERROR_TEXT);
|
|
83
|
+
const bounded = codePoints(scrubCredentialText(scanned.text, scanned.cut), MAX_ERROR_TEXT);
|
|
82
84
|
return bounded.cut || scanned.cut ? `${bounded.text}…` : bounded.text;
|
|
83
85
|
}
|
|
84
86
|
/** An OpenAI MCP call's `error`: its text, or an error object's string `message`. */
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/** Whether a field name names a credential: one of `credentialKeys`, or a name ending in `token`,
|
|
2
|
+
* `secret`, `password`, `apikey` or `credential`, ignoring case, `-` and `_`. */
|
|
3
|
+
export declare function isCredentialKey(key: string): boolean;
|
|
1
4
|
/**
|
|
2
5
|
* Removes credentials from free text a provider returned, such as an MCP call's error message,
|
|
3
6
|
* with the rules tool definitions use, extended for text: each `http`, `https`, `ws`, `wss` or
|
|
@@ -6,10 +9,18 @@
|
|
|
6
9
|
* becomes `[redacted]` when it has an `@`, `?` or `#`; a token with a known credential prefix
|
|
7
10
|
* (`hue_sk_`, `sk-`, `xoxb-`, `ya29.` and others), the credential after an authorization scheme
|
|
8
11
|
* (`Bearer`, `Basic`, `Token`), the whole value of an `Authorization` header, and the value of a
|
|
9
|
-
* `key=value` or `key
|
|
10
|
-
* become `[redacted]`.
|
|
12
|
+
* `key=value`, `key: value` or `key => value` pair whose key names a credential (quoted,
|
|
13
|
+
* escaped-quoted, bare, or a whole `[…]` or `{…}`) become `[redacted]`. A JSON or `%` escape
|
|
14
|
+
* (`\n`, `\u0022`, `%20`) ends a word as a space does. A quote that does not close on its line
|
|
15
|
+
* runs to the end of the line, and a URL's quoted query value is replaced whole. `cut` says the
|
|
16
|
+
* text was cut from a longer one, so a URL or prefixed token that runs to its end is replaced
|
|
17
|
+
* whole, as is the word of scheme characters it ends in, which may start a URL's scheme. Only the
|
|
18
|
+
* first 16,384 code points are read: a longer text is cut there, and `…` marks it.
|
|
11
19
|
*/
|
|
12
|
-
export declare function scrubCredentialText(text: string): string;
|
|
20
|
+
export declare function scrubCredentialText(text: string, cut?: boolean): string;
|
|
21
|
+
/** `scrubCredentialText` without its bound on the text's length, for tests that time long texts;
|
|
22
|
+
* callers use `scrubCredentialText`. */
|
|
23
|
+
export declare function scrubCredentialTextUnbounded(text: string, cut?: boolean): string;
|
|
13
24
|
/**
|
|
14
25
|
* Removes hosted-tool credentials from an exported attribute value, before the caller's `redact`.
|
|
15
26
|
* Tool definitions come from OpenTelemetry GenAI (`gen_ai.tool.definitions`), AI SDK 6
|