@osama.ansar/agent-loopguard 0.1.0 → 0.2.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/CHANGELOG.md +23 -0
- package/README.md +190 -18
- package/dist/index.cjs +840 -119
- package/dist/index.d.cts +259 -9
- package/dist/index.d.ts +259 -9
- package/dist/index.js +839 -120
- package/package.json +2 -1
package/dist/index.d.cts
CHANGED
|
@@ -42,24 +42,32 @@ interface GuardStep {
|
|
|
42
42
|
/** When the step happened (epoch ms). Informational: recorded in history, not used by detectors. */
|
|
43
43
|
timestamp?: number | undefined;
|
|
44
44
|
}
|
|
45
|
-
type StopReason = 'max-steps' | 'repeated-tool-call' | 'oscillation' | 'no-progress' | 'finish-reason' | 'budget' | 'custom';
|
|
45
|
+
type StopReason = 'max-steps' | 'tool-limit' | 'repeated-tool-call' | 'oscillation' | 'no-progress' | 'finish-reason' | 'budget' | 'custom';
|
|
46
46
|
type BudgetMetric = 'totalTokens' | 'inputTokens' | 'outputTokens' | 'costUsd' | 'durationMs';
|
|
47
47
|
/** Stable machine-readable codes. Safe to switch on; new codes are only added in minor versions. */
|
|
48
|
-
type BuiltinStopCode = 'MAX_STEPS' | 'REPEATED_TOOL_CALL' | 'OSCILLATION' | 'NO_PROGRESS' | 'FINISH_TERMINAL' | 'FINISH_OTHER' | 'FINISH_OTHER_TEXT_ONLY' | 'BUDGET_TOTAL_TOKENS' | 'BUDGET_INPUT_TOKENS' | 'BUDGET_OUTPUT_TOKENS' | 'BUDGET_COST_USD' | 'BUDGET_DURATION_MS';
|
|
48
|
+
type BuiltinStopCode = 'MAX_STEPS' | 'TOOL_CALL_CAP' | 'REPEATED_TOOL_CALL' | 'OSCILLATION' | 'NO_PROGRESS' | 'FINISH_TERMINAL' | 'FINISH_OTHER' | 'FINISH_OTHER_TEXT_ONLY' | 'BUDGET_TOTAL_TOKENS' | 'BUDGET_INPUT_TOKENS' | 'BUDGET_OUTPUT_TOKENS' | 'BUDGET_COST_USD' | 'BUDGET_DURATION_MS';
|
|
49
49
|
interface MaxStepsEvidence {
|
|
50
50
|
steps: number;
|
|
51
51
|
limit: number;
|
|
52
52
|
}
|
|
53
|
+
interface ToolLimitEvidence {
|
|
54
|
+
tool: string;
|
|
55
|
+
/** Calls to the tool in this run, counting the one that went over. */
|
|
56
|
+
calls: number;
|
|
57
|
+
/** The tool's `maxCalls`. */
|
|
58
|
+
limit: number;
|
|
59
|
+
}
|
|
53
60
|
interface RepeatedToolCallEvidence {
|
|
54
61
|
tool: string;
|
|
55
62
|
/** Canonical form of the arguments, truncated for display. */
|
|
56
63
|
argsPreview: string;
|
|
57
64
|
/** Length of the run of identical calls. */
|
|
58
65
|
count: number;
|
|
66
|
+
/** The threshold that applied to this tool (the global one unless the tool's policy changes it). */
|
|
59
67
|
threshold: number;
|
|
60
68
|
/** Indexes (0-based) of the steps that contain the run; at most the last 10. */
|
|
61
69
|
stepIndexes: number[];
|
|
62
|
-
/** True when
|
|
70
|
+
/** True when identical results were required too (the global option, or a `polling` tool). */
|
|
63
71
|
identicalResults: boolean;
|
|
64
72
|
}
|
|
65
73
|
interface OscillationEvidence {
|
|
@@ -70,6 +78,8 @@ interface OscillationEvidence {
|
|
|
70
78
|
threshold: number;
|
|
71
79
|
/** One cycle, as `tool(args)` labels. */
|
|
72
80
|
cycle: string[];
|
|
81
|
+
/** The tool name of each call in the cycle (no arguments), in the same order as `cycle`. */
|
|
82
|
+
tools: string[];
|
|
73
83
|
}
|
|
74
84
|
interface NoProgressEvidence {
|
|
75
85
|
/** Consecutive stalled steps with identical text. */
|
|
@@ -101,10 +111,18 @@ interface StopBase<R extends StopReason, C extends string, E> {
|
|
|
101
111
|
detail: string;
|
|
102
112
|
/** Structured, JSON-serialisable facts behind the decision. */
|
|
103
113
|
evidence: E;
|
|
114
|
+
/**
|
|
115
|
+
* Plain-English text meant to be pasted into the model's next turn or tool result, present on
|
|
116
|
+
* every stop that is a fault (see `isFault`). It names the tool but never repeats arguments or
|
|
117
|
+
* results, so it is safe to send to the model. Absent on a normal `stop` finish and, for a
|
|
118
|
+
* `custom` stop, unless the detector (or `options.feedback`) supplies it. See `feedbackFor`.
|
|
119
|
+
*/
|
|
120
|
+
feedback?: string;
|
|
104
121
|
/** Non-fatal warnings raised in the same step, if any. */
|
|
105
122
|
warnings?: GuardWarning[];
|
|
106
123
|
}
|
|
107
124
|
type MaxStepsVerdict = StopBase<'max-steps', 'MAX_STEPS', MaxStepsEvidence>;
|
|
125
|
+
type ToolLimitVerdict = StopBase<'tool-limit', 'TOOL_CALL_CAP', ToolLimitEvidence>;
|
|
108
126
|
type RepeatedToolCallVerdict = StopBase<'repeated-tool-call', 'REPEATED_TOOL_CALL', RepeatedToolCallEvidence>;
|
|
109
127
|
type OscillationVerdict = StopBase<'oscillation', 'OSCILLATION', OscillationEvidence>;
|
|
110
128
|
type NoProgressVerdict = StopBase<'no-progress', 'NO_PROGRESS', NoProgressEvidence>;
|
|
@@ -112,7 +130,7 @@ type FinishReasonVerdict = StopBase<'finish-reason', 'FINISH_TERMINAL' | 'FINISH
|
|
|
112
130
|
type BudgetVerdict = StopBase<'budget', 'BUDGET_TOTAL_TOKENS' | 'BUDGET_INPUT_TOKENS' | 'BUDGET_OUTPUT_TOKENS' | 'BUDGET_COST_USD' | 'BUDGET_DURATION_MS', BudgetEvidence>;
|
|
113
131
|
/** Verdict produced by a user-supplied `custom` detector. */
|
|
114
132
|
type CustomVerdict = StopBase<'custom', string, unknown>;
|
|
115
|
-
type StopVerdict = MaxStepsVerdict | RepeatedToolCallVerdict | OscillationVerdict | NoProgressVerdict | FinishReasonVerdict | BudgetVerdict | CustomVerdict;
|
|
133
|
+
type StopVerdict = MaxStepsVerdict | ToolLimitVerdict | RepeatedToolCallVerdict | OscillationVerdict | NoProgressVerdict | FinishReasonVerdict | BudgetVerdict | CustomVerdict;
|
|
116
134
|
interface GuardWarning {
|
|
117
135
|
code: 'BUDGET_WARNING';
|
|
118
136
|
metric: BudgetMetric;
|
|
@@ -182,6 +200,8 @@ interface CustomStop {
|
|
|
182
200
|
detail?: string;
|
|
183
201
|
/** Anything JSON-serialisable that explains the decision. */
|
|
184
202
|
evidence?: unknown;
|
|
203
|
+
/** Text for the model, becomes `verdict.feedback`. Default: none. Must not contain secrets. */
|
|
204
|
+
feedback?: string;
|
|
185
205
|
}
|
|
186
206
|
/**
|
|
187
207
|
* User-supplied detector. Receives the full history (including `step`, last) and may return a
|
|
@@ -191,6 +211,35 @@ interface CustomStop {
|
|
|
191
211
|
type CustomDetector = (history: readonly GuardStep[], step: GuardStep) => CustomStop | {
|
|
192
212
|
stop: false;
|
|
193
213
|
} | undefined;
|
|
214
|
+
/**
|
|
215
|
+
* Rules for one tool, keyed by tool name in `GuardOptions.tools`. Every field is optional. See the
|
|
216
|
+
* README ("Per-tool policies") for how they combine with the global detectors.
|
|
217
|
+
*/
|
|
218
|
+
interface ToolPolicy {
|
|
219
|
+
/**
|
|
220
|
+
* Identical arguments are legitimate for this tool as long as the results keep changing (a job
|
|
221
|
+
* status poll, a paginated read). The repeated-call rule then applies only when the results are
|
|
222
|
+
* identical too, after `maxIdenticalResults` identical outcomes in a row (default: the tool's
|
|
223
|
+
* `repeatThreshold`, else the global threshold). `true` is the same as `{}`.
|
|
224
|
+
*/
|
|
225
|
+
polling?: boolean | {
|
|
226
|
+
maxIdenticalResults?: number;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* At most this many calls to the tool in one run (integer >= 0; `0` forbids the tool). The call
|
|
230
|
+
* after the limit stops the run with `TOOL_CALL_CAP` (and `guard.preflight` denies it before it runs).
|
|
231
|
+
*/
|
|
232
|
+
maxCalls?: number;
|
|
233
|
+
/** Stop after this many identical calls in a row to this tool. Integer >= 2. Overrides the global threshold. */
|
|
234
|
+
repeatThreshold?: number;
|
|
235
|
+
/**
|
|
236
|
+
* Leave the tool out of repeat, oscillation and no-progress detection and out of `maxCalls`
|
|
237
|
+
* (for bookkeeping tools such as `think` or `todo`). Takes precedence over the other fields.
|
|
238
|
+
*/
|
|
239
|
+
ignore?: boolean;
|
|
240
|
+
}
|
|
241
|
+
/** Where a piece of feedback is going: after a step was recorded, or in place of a call that was not run. */
|
|
242
|
+
type FeedbackPhase = 'check' | 'preflight';
|
|
194
243
|
interface GuardOptions {
|
|
195
244
|
/** Stop after this many steps. Integer >= 1. Default 50. `false` disables. */
|
|
196
245
|
maxSteps?: number | false;
|
|
@@ -204,8 +253,18 @@ interface GuardOptions {
|
|
|
204
253
|
finishReason?: FinishReasonOptions | false;
|
|
205
254
|
/** Default: no limits. */
|
|
206
255
|
budget?: BudgetOptions | false;
|
|
256
|
+
/** Per-tool rules by tool name; tools that are not listed follow the global options. */
|
|
257
|
+
tools?: Readonly<Record<string, ToolPolicy>>;
|
|
207
258
|
/** Extra detectors, run after the built-in ones. */
|
|
208
259
|
custom?: CustomDetector | readonly CustomDetector[];
|
|
260
|
+
/**
|
|
261
|
+
* Replace the model-facing text of a fault verdict (and of a `preflight` denial). Return a string
|
|
262
|
+
* to use it, or `undefined` to keep the default (`feedbackFor`). Errors it throws propagate out of
|
|
263
|
+
* `guard.check` / `guard.preflight`. The text is yours to keep free of secrets.
|
|
264
|
+
*/
|
|
265
|
+
feedback?: (verdict: StopVerdict, info: {
|
|
266
|
+
phase: FeedbackPhase;
|
|
267
|
+
}) => string | undefined;
|
|
209
268
|
/** Clock used for wall-clock duration budgets. Default `Date.now`. */
|
|
210
269
|
now?: () => number;
|
|
211
270
|
}
|
|
@@ -229,6 +288,7 @@ interface GuardSummary {
|
|
|
229
288
|
remaining: number;
|
|
230
289
|
} | null;
|
|
231
290
|
repeatedToolCall: {
|
|
291
|
+
/** The global threshold; tools with their own `repeatThreshold` or `polling` policy can differ. */
|
|
232
292
|
threshold: number;
|
|
233
293
|
currentRun: {
|
|
234
294
|
tool: string;
|
|
@@ -255,18 +315,175 @@ interface GuardSummary {
|
|
|
255
315
|
limits: Partial<Record<BudgetMetric, number>>;
|
|
256
316
|
used: Record<BudgetMetric, number>;
|
|
257
317
|
} | null;
|
|
318
|
+
/** Calls so far against each tool's `maxCalls`. Present only when at least one tool has a cap. */
|
|
319
|
+
toolLimits?: Array<{
|
|
320
|
+
tool: string;
|
|
321
|
+
limit: number;
|
|
322
|
+
calls: number;
|
|
323
|
+
}>;
|
|
258
324
|
};
|
|
259
325
|
/** The verdict returned by the most recent `check`, or `null` before the first one. */
|
|
260
326
|
lastVerdict: Verdict | null;
|
|
261
327
|
}
|
|
328
|
+
/** A tool call that has not run yet: all `preflight` needs is the name and the arguments. */
|
|
329
|
+
interface PreflightCall {
|
|
330
|
+
name: string;
|
|
331
|
+
args?: unknown;
|
|
332
|
+
}
|
|
333
|
+
/** The call may go ahead (as far as the rules `preflight` can evaluate are concerned). */
|
|
334
|
+
interface PreflightAllow {
|
|
335
|
+
allow: true;
|
|
336
|
+
/** Budget warnings that apply right now, if any. */
|
|
337
|
+
warnings?: GuardWarning[];
|
|
338
|
+
}
|
|
339
|
+
interface DenyBase<R extends StopReason, C extends string, E> {
|
|
340
|
+
allow: false;
|
|
341
|
+
/** Same vocabulary as `StopVerdict.reason`. */
|
|
342
|
+
reason: R;
|
|
343
|
+
/** Same vocabulary as `StopVerdict.code`. */
|
|
344
|
+
code: C;
|
|
345
|
+
/** One developer-facing sentence. May contain argument previews, like `StopVerdict.detail`. */
|
|
346
|
+
detail: string;
|
|
347
|
+
/** Structured, JSON-serialisable facts behind the decision. */
|
|
348
|
+
evidence: E;
|
|
349
|
+
/** Text to give the model in place of the tool's result. Never repeats arguments or results. */
|
|
350
|
+
feedback: string;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* The call should not run. Only the rules that can be judged before a call runs appear here:
|
|
354
|
+
* `max-steps`, `budget`, `tool-limit`, `repeated-tool-call` and `oscillation`.
|
|
355
|
+
*/
|
|
356
|
+
type PreflightDeny = DenyBase<'max-steps', 'MAX_STEPS', MaxStepsEvidence> | DenyBase<'budget', BudgetVerdict['code'], BudgetEvidence> | DenyBase<'tool-limit', 'TOOL_CALL_CAP', ToolLimitEvidence> | DenyBase<'repeated-tool-call', 'REPEATED_TOOL_CALL', RepeatedToolCallEvidence> | DenyBase<'oscillation', 'OSCILLATION', OscillationEvidence>;
|
|
357
|
+
type Preflight = PreflightAllow | PreflightDeny;
|
|
358
|
+
/** The stop verdicts a `preflight` denial is made from. */
|
|
359
|
+
type PreflightStopVerdict = MaxStepsVerdict | BudgetVerdict | ToolLimitVerdict | RepeatedToolCallVerdict | OscillationVerdict;
|
|
360
|
+
/** The current snapshot format. A guard only reads snapshots of the version it knows. */
|
|
361
|
+
type GuardSnapshotVersion = 1;
|
|
362
|
+
/**
|
|
363
|
+
* One short fingerprint per group of options, so a snapshot can tell whether it is being restored
|
|
364
|
+
* under the options it was taken with. The options themselves are not stored.
|
|
365
|
+
*/
|
|
366
|
+
interface GuardOptionsFingerprint {
|
|
367
|
+
maxSteps: string;
|
|
368
|
+
repeatedToolCall: string;
|
|
369
|
+
oscillation: string;
|
|
370
|
+
noProgress: string;
|
|
371
|
+
finishReason: string;
|
|
372
|
+
budget: string;
|
|
373
|
+
tools: string;
|
|
374
|
+
/** Covers the number of custom detectors, not what they do. */
|
|
375
|
+
custom: string;
|
|
376
|
+
}
|
|
377
|
+
/** The run of identical calls that `repeatedToolCall` is currently counting. */
|
|
378
|
+
interface RepeatedToolCallSnapshot {
|
|
379
|
+
/** Hash identifying the repeated call (or call and result); `null` when there is no run. */
|
|
380
|
+
key: string | null;
|
|
381
|
+
tool: string;
|
|
382
|
+
/** Truncated canonical arguments (at most 80 characters), kept so evidence reads the same after a restore. */
|
|
383
|
+
preview: string;
|
|
384
|
+
length: number;
|
|
385
|
+
/** Indexes of the newest steps in the run (at most 10). */
|
|
386
|
+
steps: number[];
|
|
387
|
+
longest: number;
|
|
388
|
+
}
|
|
389
|
+
/** The newest calls the oscillation rule compares against, as hashes plus short labels. */
|
|
390
|
+
interface OscillationSnapshot {
|
|
391
|
+
sigs: string[];
|
|
392
|
+
/** `tool(argument preview)` for each call in `sigs`. */
|
|
393
|
+
labels: string[];
|
|
394
|
+
/** Tool name of each call in `sigs`. */
|
|
395
|
+
names: string[];
|
|
396
|
+
matches: number[];
|
|
397
|
+
current: {
|
|
398
|
+
period: number;
|
|
399
|
+
repeats: number;
|
|
400
|
+
} | null;
|
|
401
|
+
}
|
|
402
|
+
interface NoProgressSnapshot {
|
|
403
|
+
/** Hashes of the most recent distinct tool outcomes, oldest first. */
|
|
404
|
+
seen: string[];
|
|
405
|
+
streak: number;
|
|
406
|
+
/** Hash of the text the current streak shares; `null` when there is no streak. */
|
|
407
|
+
textKey: string | null;
|
|
408
|
+
/** Truncated text of the streak (at most 80 characters). */
|
|
409
|
+
textPreview: string;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Everything a guard needs to carry on a run in another process, as plain JSON-safe data.
|
|
413
|
+
*
|
|
414
|
+
* Contains: counters, running totals, elapsed wall-clock time (only when a duration budget exists),
|
|
415
|
+
* hashes of recent tool calls and outcomes, tool names, and a few truncated previews (at most 80
|
|
416
|
+
* characters each) of recent arguments and text, so that evidence and messages read the same after a
|
|
417
|
+
* restore. Does not contain: raw arguments, results, errors, model text, the step history, the
|
|
418
|
+
* options, or the last verdict. `snapshot({ redact: true })` also replaces the previews.
|
|
419
|
+
* Hashes are not cryptographic: a short, guessable value could be recovered by trying candidates.
|
|
420
|
+
*/
|
|
421
|
+
interface GuardSnapshot {
|
|
422
|
+
version: GuardSnapshotVersion;
|
|
423
|
+
steps: number;
|
|
424
|
+
toolCalls: number;
|
|
425
|
+
failedToolCalls: number;
|
|
426
|
+
totals: GuardTotals;
|
|
427
|
+
/** Milliseconds of wall-clock time elapsed when the snapshot was taken; `null` without a duration budget. */
|
|
428
|
+
wallClockMs: number | null;
|
|
429
|
+
options: GuardOptionsFingerprint;
|
|
430
|
+
/** `null` for a detector that is disabled. */
|
|
431
|
+
detectors: {
|
|
432
|
+
repeatedToolCall: RepeatedToolCallSnapshot | null;
|
|
433
|
+
oscillation: OscillationSnapshot | null;
|
|
434
|
+
noProgress: NoProgressSnapshot | null;
|
|
435
|
+
finishReason: {
|
|
436
|
+
lastFinishReason: string | null;
|
|
437
|
+
} | null;
|
|
438
|
+
/** Calls so far for each tool with a `maxCalls`, in configuration order; `null` when no tool has one. */
|
|
439
|
+
toolLimits: Array<{
|
|
440
|
+
tool: string;
|
|
441
|
+
calls: number;
|
|
442
|
+
}> | null;
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
interface SnapshotOptions {
|
|
446
|
+
/**
|
|
447
|
+
* Replace the argument and text previews in the snapshot with `[redacted]`. Stop decisions stay
|
|
448
|
+
* identical after a restore, but evidence and messages that quote those previews will say
|
|
449
|
+
* `[redacted]` for calls made before the snapshot. Default `false`.
|
|
450
|
+
*/
|
|
451
|
+
redact?: boolean;
|
|
452
|
+
}
|
|
453
|
+
interface RestoreOptions {
|
|
454
|
+
/**
|
|
455
|
+
* Allow `maxSteps` and `budget` to differ from the options the snapshot was taken with, for
|
|
456
|
+
* example to give a run that hit its limit more room. Every other option must still match.
|
|
457
|
+
* Default `false`.
|
|
458
|
+
*/
|
|
459
|
+
allowLimitChanges?: boolean;
|
|
460
|
+
}
|
|
262
461
|
interface Guard {
|
|
263
462
|
/** Record a step and decide whether the run should continue. Never throws on odd step data. */
|
|
264
463
|
check(step: GuardStep): Verdict;
|
|
464
|
+
/**
|
|
465
|
+
* Would this call (or these parallel calls) trip a rule if it ran now? Records nothing and does
|
|
466
|
+
* not change the guard: call it as often as you like, then still `check` the finished step.
|
|
467
|
+
* Evaluates only the rules that need no results, text, finish reason or usage; see the README
|
|
468
|
+
* ("Preflight") for the exact list. Never throws on odd call data.
|
|
469
|
+
*/
|
|
470
|
+
preflight(call: PreflightCall | readonly PreflightCall[]): Preflight;
|
|
265
471
|
/** Forget everything and start a fresh run (options are kept). */
|
|
266
472
|
reset(): void;
|
|
473
|
+
/**
|
|
474
|
+
* Plain, JSON-safe state for carrying the run into another process; restore it with
|
|
475
|
+
* `createGuard.fromJSON`. Does not change the guard. Because it is called `toJSON`,
|
|
476
|
+
* `JSON.stringify(guard)` gives the same data. See `GuardSnapshot` for what it holds.
|
|
477
|
+
*/
|
|
478
|
+
toJSON(): GuardSnapshot;
|
|
479
|
+
/** Same as `toJSON`, with options. */
|
|
480
|
+
snapshot(options?: SnapshotOptions): GuardSnapshot;
|
|
267
481
|
/** Counts, totals and per-detector state. Contains nothing time-dependent. */
|
|
268
482
|
summary(): GuardSummary;
|
|
269
|
-
/**
|
|
483
|
+
/**
|
|
484
|
+
* Frozen shallow copy of the steps recorded so far by this guard object. A guard restored from a
|
|
485
|
+
* snapshot starts with an empty history: the raw steps are not part of a snapshot.
|
|
486
|
+
*/
|
|
270
487
|
readonly history: readonly GuardStep[];
|
|
271
488
|
}
|
|
272
489
|
|
|
@@ -276,19 +493,52 @@ declare const DEFAULT_MAX_STEPS = 50;
|
|
|
276
493
|
* Create a guard. Feed it one step at a time with `check`; it answers `{ stop: false }` or a
|
|
277
494
|
* typed verdict saying why the run should end.
|
|
278
495
|
*
|
|
279
|
-
* Detectors run in this order and the first stop wins: finish reason, budget, max steps,
|
|
280
|
-
* repeated tool call, oscillation, no progress, then custom detectors. All of them see
|
|
281
|
-
* even after one has stopped, so their state stays consistent.
|
|
496
|
+
* Detectors run in this order and the first stop wins: finish reason, budget, max steps, tool
|
|
497
|
+
* limit, repeated tool call, oscillation, no progress, then custom detectors. All of them see
|
|
498
|
+
* every step even after one has stopped, so their state stays consistent.
|
|
499
|
+
*
|
|
500
|
+
* Tools with `ignore: true` in `options.tools` are removed from the calls the tool-limit,
|
|
501
|
+
* repeated-call, oscillation and no-progress detectors see.
|
|
282
502
|
*
|
|
283
503
|
* Invalid options throw a `TypeError` here, never later from `check`.
|
|
504
|
+
*
|
|
505
|
+
* `createGuard.fromJSON(snapshot, options)` (also exported as `restoreGuard`) continues a run from
|
|
506
|
+
* `guard.toJSON()`.
|
|
284
507
|
*/
|
|
285
508
|
declare function createGuard(options?: GuardOptions): Guard;
|
|
509
|
+
declare namespace createGuard {
|
|
510
|
+
var fromJSON: typeof restoreGuard;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Rebuild a guard from a snapshot (`guard.toJSON()`), so that it goes on exactly where the original
|
|
514
|
+
* stopped: given the same steps, it gives the same verdicts.
|
|
515
|
+
*
|
|
516
|
+
* Pass the same `options` the snapshot was taken with. They are not stored (functions cannot
|
|
517
|
+
* be), only fingerprinted, so a mismatch throws a `TypeError` naming the option groups that differ
|
|
518
|
+
* instead of silently behaving differently. `restoreOptions.allowLimitChanges` relaxes that for
|
|
519
|
+
* `maxSteps` and `budget` only. `now`, `feedback` and the code of custom detectors are not checked.
|
|
520
|
+
*
|
|
521
|
+
* Anything wrong with the snapshot (unknown version, wrong shape, hostile values) throws a
|
|
522
|
+
* `TypeError` here, never later from `check`. `snapshot` may be the result of `JSON.parse`.
|
|
523
|
+
*/
|
|
524
|
+
declare function restoreGuard(snapshot: unknown, options?: GuardOptions, restoreOptions?: RestoreOptions): Guard;
|
|
286
525
|
|
|
287
526
|
/** True for a stop verdict that is not just the model finishing normally (`finishReason: 'stop'`). */
|
|
288
527
|
declare function isFault(verdict: Verdict): verdict is StopVerdict;
|
|
289
528
|
/** Turn a verdict into readable text for logs and error messages. Never throws. */
|
|
290
529
|
declare function explain(verdict: Verdict): string;
|
|
291
530
|
|
|
531
|
+
/**
|
|
532
|
+
* The default model-facing text for a stop verdict, or `undefined` when there is none: a normal
|
|
533
|
+
* `stop` finish (not a fault), and a `custom` verdict that did not bring its own `feedback`.
|
|
534
|
+
*
|
|
535
|
+
* `phase` is `'check'` (the default) for a verdict returned by `guard.check`, where the step has
|
|
536
|
+
* already happened, and `'preflight'` for a call that `guard.preflight` refused to let run. The
|
|
537
|
+
* text is deterministic: the same verdict always produces the same string.
|
|
538
|
+
*/
|
|
539
|
+
declare function feedbackFor(verdict: PreflightStopVerdict, phase?: FeedbackPhase): string;
|
|
540
|
+
declare function feedbackFor(verdict: StopVerdict, phase?: FeedbackPhase): string | undefined;
|
|
541
|
+
|
|
292
542
|
/**
|
|
293
543
|
* Canonicalisation: turn any JavaScript value into a deterministic string so that two
|
|
294
544
|
* "equal" tool-call arguments compare equal regardless of key order, and so that nothing
|
|
@@ -438,4 +688,4 @@ interface GuardedSteps<S extends GuardStep> extends AsyncIterable<S> {
|
|
|
438
688
|
*/
|
|
439
689
|
declare function withGuard<S extends GuardStep>(source: AsyncIterable<S> | Iterable<S>, guard: Guard): GuardedSteps<S>;
|
|
440
690
|
|
|
441
|
-
export { type AbortSignalLike, type AiSdkStepLike, type AiSdkToolCallLike, type AiSdkToolResultLike, type BudgetEvidence, type BudgetLimit, type BudgetMetric, type BudgetOptions, type BudgetVerdict, type BuiltinStopCode, type ContinueVerdict, type CustomDetector, type CustomStop, type CustomVerdict, DEFAULT_MAX_STEPS, type FinishReasonEvidence, type FinishReasonOptions, type FinishReasonVerdict, type Guard, type GuardOptions, type GuardStep, type GuardSummary, type GuardToolCall, type GuardTotals, type GuardUsage, type GuardWarning, type GuardedSteps, type LoopResult, type LoopStep, type MaxStepsEvidence, type MaxStepsVerdict, type NoProgressEvidence, type NoProgressOptions, type NoProgressVerdict, type OscillationEvidence, type OscillationOptions, type OscillationVerdict, type OtherFinishPolicy, type RepeatedToolCallEvidence, type RepeatedToolCallOptions, type RepeatedToolCallVerdict, type RunAgentLoopOptions, type StopReason, type StopVerdict, type ToStopWhenOptions, type Verdict, canonicalize, createGuard, explain, isFault, runAgentLoop, stableHash, toGuardStep, toStopWhen, withGuard };
|
|
691
|
+
export { type AbortSignalLike, type AiSdkStepLike, type AiSdkToolCallLike, type AiSdkToolResultLike, type BudgetEvidence, type BudgetLimit, type BudgetMetric, type BudgetOptions, type BudgetVerdict, type BuiltinStopCode, type ContinueVerdict, type CustomDetector, type CustomStop, type CustomVerdict, DEFAULT_MAX_STEPS, type FeedbackPhase, type FinishReasonEvidence, type FinishReasonOptions, type FinishReasonVerdict, type Guard, type GuardOptions, type GuardOptionsFingerprint, type GuardSnapshot, type GuardSnapshotVersion, type GuardStep, type GuardSummary, type GuardToolCall, type GuardTotals, type GuardUsage, type GuardWarning, type GuardedSteps, type LoopResult, type LoopStep, type MaxStepsEvidence, type MaxStepsVerdict, type NoProgressEvidence, type NoProgressOptions, type NoProgressSnapshot, type NoProgressVerdict, type OscillationEvidence, type OscillationOptions, type OscillationSnapshot, type OscillationVerdict, type OtherFinishPolicy, type Preflight, type PreflightAllow, type PreflightCall, type PreflightDeny, type PreflightStopVerdict, type RepeatedToolCallEvidence, type RepeatedToolCallOptions, type RepeatedToolCallSnapshot, type RepeatedToolCallVerdict, type RestoreOptions, type RunAgentLoopOptions, type SnapshotOptions, type StopReason, type StopVerdict, type ToStopWhenOptions, type ToolLimitEvidence, type ToolLimitVerdict, type ToolPolicy, type Verdict, canonicalize, createGuard, explain, feedbackFor, isFault, restoreGuard, runAgentLoop, stableHash, toGuardStep, toStopWhen, withGuard };
|