@nifrajs/testing 4.0.0 → 5.0.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 +17 -4
- package/dist/adversarial.d.ts +6 -38
- package/dist/adversarial.d.ts.map +1 -1
- package/dist/adversarial.js +304 -83
- package/dist/adversarial.js.map +1 -1
- package/dist/agent-eval.d.ts +25 -8
- package/dist/agent-eval.d.ts.map +1 -1
- package/dist/agent-eval.js +11 -6
- package/dist/agent-eval.js.map +1 -1
- package/dist/certification.d.ts +11 -1
- package/dist/certification.d.ts.map +1 -1
- package/dist/certification.js +136 -49
- package/dist/certification.js.map +1 -1
- package/dist/cookies.d.ts +1 -1
- package/dist/cookies.d.ts.map +1 -1
- package/dist/cookies.js +5 -3
- package/dist/cookies.js.map +1 -1
- package/dist/data-conformance.d.ts.map +1 -1
- package/dist/data-conformance.js +20 -8
- package/dist/data-conformance.js.map +1 -1
- package/dist/incident.d.ts +21 -6
- package/dist/incident.d.ts.map +1 -1
- package/dist/incident.js +99 -23
- package/dist/incident.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/trajectory.d.ts.map +1 -1
- package/dist/trajectory.js +31 -21
- package/dist/trajectory.js.map +1 -1
- package/dist/zod.d.ts +2 -2
- package/package.json +7 -7
- package/src/adversarial.ts +378 -147
- package/src/agent-eval.ts +30 -8
- package/src/certification.ts +137 -45
- package/src/cookies.ts +4 -2
- package/src/data-conformance.ts +23 -7
- package/src/incident.ts +121 -20
- package/src/index.ts +1 -0
- package/src/trajectory.ts +28 -28
- package/src/zod.ts +2 -2
package/src/trajectory.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
runAgent,
|
|
10
10
|
} from "@nifrajs/agent"
|
|
11
11
|
import type { StandardSchemaV1 } from "@nifrajs/core/schema"
|
|
12
|
-
import {
|
|
12
|
+
import type { ToolBudget } from "@nifrajs/core/tool-contract"
|
|
13
13
|
import { createFailureLab, type FailureEvidence } from "./failure-lab.ts"
|
|
14
14
|
import type { FaultProfile, FaultProfileFault, FaultProfileFaultKind } from "./fault-profile.ts"
|
|
15
15
|
|
|
@@ -169,7 +169,32 @@ export async function replayTrajectory<
|
|
|
169
169
|
return lab.provider("trajectory.model", () => response)
|
|
170
170
|
},
|
|
171
171
|
}
|
|
172
|
-
|
|
172
|
+
// Tools run dry, so a tool's own execute never runs: its faults fire at the budget check every
|
|
173
|
+
// tool call still makes. Each replayed tool carries its own cost object, which is how that check
|
|
174
|
+
// tells a tool's charge from the model's.
|
|
175
|
+
const toolCosts = new Map<object, string>()
|
|
176
|
+
const tools = definition.tools.map((tool) => {
|
|
177
|
+
const cost = { ...tool.cost }
|
|
178
|
+
toolCosts.set(cost, tool.name)
|
|
179
|
+
return Object.freeze({ ...tool, cost })
|
|
180
|
+
})
|
|
181
|
+
const callerBudget = ports.budget
|
|
182
|
+
const budget: ToolBudget = {
|
|
183
|
+
consume: (cost) => {
|
|
184
|
+
const tool = cost === undefined ? undefined : toolCosts.get(cost)
|
|
185
|
+
if (tool !== undefined) {
|
|
186
|
+
lab.checkpoint(`trajectory.tool.${tool}`)
|
|
187
|
+
const fault = takeFault("tool")
|
|
188
|
+
if (fault?.kind === "budget-pressure") return false
|
|
189
|
+
if (fault?.kind === "tool-error") throw new Error("trajectory tool fault")
|
|
190
|
+
// The call then stops as cancelled, and so does the run, as a cancelled model call does.
|
|
191
|
+
if (fault?.kind === "cancellation") controller.abort()
|
|
192
|
+
else lab.checkpoint(`trajectory.effect.${tool}`)
|
|
193
|
+
}
|
|
194
|
+
return callerBudget?.consume(cost) ?? true
|
|
195
|
+
},
|
|
196
|
+
snapshot: () => callerBudget?.snapshot() ?? {},
|
|
197
|
+
}
|
|
173
198
|
const replayDefinition: AgentDefinition<InputSchema, OutputSchema> = { ...definition, tools }
|
|
174
199
|
let effectiveApproval = ports.approval
|
|
175
200
|
if (effectiveApproval !== undefined) {
|
|
@@ -182,17 +207,14 @@ export async function replayTrajectory<
|
|
|
182
207
|
},
|
|
183
208
|
}
|
|
184
209
|
}
|
|
185
|
-
const pressuredBudget: ToolBudget = createToolBudget({ limits: { calls: 0 } })
|
|
186
210
|
const effectivePorts: AgentPorts = {
|
|
187
211
|
...ports,
|
|
188
212
|
model,
|
|
189
213
|
dryRun: true,
|
|
190
214
|
signal: controller.signal,
|
|
215
|
+
budget,
|
|
191
216
|
idFactory: () => `trajectory-${seed}-${++idSequence}`,
|
|
192
217
|
...(effectiveApproval === undefined ? {} : { approval: effectiveApproval }),
|
|
193
|
-
...(faults.some((fault) => fault.kind === "budget-pressure")
|
|
194
|
-
? { budget: pressuredBudget }
|
|
195
|
-
: {}),
|
|
196
218
|
}
|
|
197
219
|
const result = await runAgent(replayDefinition, input, effectivePorts, {
|
|
198
220
|
state: options.state,
|
|
@@ -284,28 +306,6 @@ export async function trajectoryRegressionId(
|
|
|
284
306
|
return digest({ transcript: transcript.digest, faultProfile, invariant })
|
|
285
307
|
}
|
|
286
308
|
|
|
287
|
-
function wrapTool<Input, Output>(
|
|
288
|
-
tool: ToolContract<Input, Output>,
|
|
289
|
-
lab: ReturnType<typeof createFailureLab>,
|
|
290
|
-
nextFault: () => FaultProfileFault | undefined,
|
|
291
|
-
): ToolContract<Input, Output> {
|
|
292
|
-
return Object.freeze({
|
|
293
|
-
...tool,
|
|
294
|
-
execute: async (
|
|
295
|
-
input: Input,
|
|
296
|
-
context: Parameters<ToolContract<Input, Output>["execute"]>[1],
|
|
297
|
-
) => {
|
|
298
|
-
lab.checkpoint(`trajectory.tool.${tool.name}`)
|
|
299
|
-
const fault = nextFault()
|
|
300
|
-
if (fault?.kind === "tool-error" || fault?.kind === "budget-pressure")
|
|
301
|
-
throw new Error("trajectory tool fault")
|
|
302
|
-
if (fault?.kind === "cancellation") throw new Error("trajectory cancellation")
|
|
303
|
-
lab.checkpoint(`trajectory.effect.${tool.name}`)
|
|
304
|
-
return tool.execute(input, context)
|
|
305
|
-
},
|
|
306
|
-
})
|
|
307
|
-
}
|
|
308
|
-
|
|
309
309
|
function validateAgentTranscript(value: AgentTranscript): void {
|
|
310
310
|
if (
|
|
311
311
|
value === null ||
|
package/src/zod.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* carries no `.jsonSchema`, so without a bridge the laboratory reports NO_WITNESS for every zod route and
|
|
5
5
|
* emits only generic type-confusion mutations, and the mock server returns `{}` for zod responses.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* The laboratory and the mock server apply the same conversion AUTOMATICALLY through `@nifrajs/mock`'s
|
|
8
|
+
* `autoReflectJsonSchema`, which reads a zod schema's own converter - no wiring. This module remains the
|
|
9
9
|
* EXPLICIT form: pass it when you want the conversion pinned regardless of the default's behavior, or as
|
|
10
10
|
* the base of a custom hook that handles more vendors:
|
|
11
11
|
*
|