@attest-ai/core 0.5.0 → 0.9.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/dist/cjs/index.cjs +741 -25
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +145 -8
- package/dist/cjs/proto/index.cjs +81 -0
- package/dist/cjs/proto/index.cjs.map +1 -1
- package/dist/cjs/proto/index.d.cts +145 -3
- package/dist/esm/cli.js +321 -2
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/index.d.ts +145 -8
- package/dist/esm/index.js +724 -25
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/proto/index.d.ts +145 -3
- package/dist/esm/proto/index.js +77 -0
- package/dist/esm/proto/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/adapters/anthropic.d.ts +0 -31
- package/dist/adapters/anthropic.d.ts.map +0 -1
- package/dist/adapters/anthropic.js +0 -42
- package/dist/adapters/anthropic.js.map +0 -1
- package/dist/adapters/gemini.d.ts +0 -30
- package/dist/adapters/gemini.d.ts.map +0 -1
- package/dist/adapters/gemini.js +0 -41
- package/dist/adapters/gemini.js.map +0 -1
- package/dist/adapters/index.d.ts +0 -11
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -7
- package/dist/adapters/index.js.map +0 -1
- package/dist/adapters/manual.d.ts +0 -9
- package/dist/adapters/manual.d.ts.map +0 -1
- package/dist/adapters/manual.js +0 -16
- package/dist/adapters/manual.js.map +0 -1
- package/dist/adapters/ollama.d.ts +0 -19
- package/dist/adapters/ollama.d.ts.map +0 -1
- package/dist/adapters/ollama.js +0 -30
- package/dist/adapters/ollama.js.map +0 -1
- package/dist/adapters/openai.d.ts +0 -34
- package/dist/adapters/openai.d.ts.map +0 -1
- package/dist/adapters/openai.js +0 -42
- package/dist/adapters/openai.js.map +0 -1
- package/dist/adapters/otel.d.ts +0 -25
- package/dist/adapters/otel.d.ts.map +0 -1
- package/dist/adapters/otel.js +0 -133
- package/dist/adapters/otel.js.map +0 -1
- package/dist/agent.d.ts +0 -14
- package/dist/agent.d.ts.map +0 -1
- package/dist/agent.js +0 -54
- package/dist/agent.js.map +0 -1
- package/dist/client.d.ts +0 -23
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -171
- package/dist/client.js.map +0 -1
- package/dist/config.d.ts +0 -21
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -31
- package/dist/config.js.map +0 -1
- package/dist/context.d.ts +0 -4
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -3
- package/dist/context.js.map +0 -1
- package/dist/delegate.d.ts +0 -3
- package/dist/delegate.d.ts.map +0 -1
- package/dist/delegate.js +0 -24
- package/dist/delegate.js.map +0 -1
- package/dist/engine-downloader.d.ts +0 -7
- package/dist/engine-downloader.d.ts.map +0 -1
- package/dist/engine-downloader.js +0 -136
- package/dist/engine-downloader.js.map +0 -1
- package/dist/engine-manager.d.ts +0 -26
- package/dist/engine-manager.d.ts.map +0 -1
- package/dist/engine-manager.js +0 -172
- package/dist/engine-manager.js.map +0 -1
- package/dist/expect.d.ts +0 -133
- package/dist/expect.d.ts.map +0 -1
- package/dist/expect.js +0 -330
- package/dist/expect.js.map +0 -1
- package/dist/index.d.ts +0 -16
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -15
- package/dist/index.js.map +0 -1
- package/dist/proto/codec.d.ts +0 -20
- package/dist/proto/codec.d.ts.map +0 -1
- package/dist/proto/codec.js +0 -71
- package/dist/proto/codec.js.map +0 -1
- package/dist/proto/constants.d.ts +0 -21
- package/dist/proto/constants.d.ts.map +0 -1
- package/dist/proto/constants.js +0 -25
- package/dist/proto/constants.js.map +0 -1
- package/dist/proto/errors.d.ts +0 -13
- package/dist/proto/errors.d.ts.map +0 -1
- package/dist/proto/errors.js +0 -24
- package/dist/proto/errors.js.map +0 -1
- package/dist/proto/index.d.ts +0 -5
- package/dist/proto/index.d.ts.map +0 -1
- package/dist/proto/index.js +0 -5
- package/dist/proto/index.js.map +0 -1
- package/dist/proto/types.d.ts +0 -104
- package/dist/proto/types.d.ts.map +0 -1
- package/dist/proto/types.js +0 -2
- package/dist/proto/types.js.map +0 -1
- package/dist/result.d.ts +0 -15
- package/dist/result.d.ts.map +0 -1
- package/dist/result.js +0 -32
- package/dist/result.js.map +0 -1
- package/dist/simulation.d.ts +0 -8
- package/dist/simulation.d.ts.map +0 -1
- package/dist/simulation.js +0 -21
- package/dist/simulation.js.map +0 -1
- package/dist/tier.d.ts +0 -5
- package/dist/tier.d.ts.map +0 -1
- package/dist/tier.js +0 -10
- package/dist/tier.js.map +0 -1
- package/dist/trace-tree.d.ts +0 -20
- package/dist/trace-tree.d.ts.map +0 -1
- package/dist/trace-tree.js +0 -92
- package/dist/trace-tree.js.map +0 -1
- package/dist/trace.d.ts +0 -41
- package/dist/trace.d.ts.map +0 -1
- package/dist/trace.js +0 -88
- package/dist/trace.js.map +0 -1
- package/dist/version.d.ts +0 -3
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -3
- package/dist/version.js.map +0 -1
package/dist/esm/index.js
CHANGED
|
@@ -31,6 +31,27 @@ function assertionId(id) {
|
|
|
31
31
|
function agentId(id) {
|
|
32
32
|
return id;
|
|
33
33
|
}
|
|
34
|
+
function layerForType(assertionType) {
|
|
35
|
+
switch (assertionType) {
|
|
36
|
+
case "schema":
|
|
37
|
+
return 1;
|
|
38
|
+
case "constraint":
|
|
39
|
+
return 2;
|
|
40
|
+
case "trace":
|
|
41
|
+
case "trace_tree":
|
|
42
|
+
return 3;
|
|
43
|
+
case "content":
|
|
44
|
+
return 4;
|
|
45
|
+
case "embedding":
|
|
46
|
+
return 5;
|
|
47
|
+
case "llm_judge":
|
|
48
|
+
return 6;
|
|
49
|
+
case "plugin":
|
|
50
|
+
return 8;
|
|
51
|
+
default:
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
34
55
|
|
|
35
56
|
// src/proto/errors.ts
|
|
36
57
|
var ProtocolError = class extends Error {
|
|
@@ -57,6 +78,58 @@ var EngineTimeoutError = class extends Error {
|
|
|
57
78
|
this.timeoutMs = timeoutMs;
|
|
58
79
|
}
|
|
59
80
|
};
|
|
81
|
+
var ProtocolDesyncError = class extends Error {
|
|
82
|
+
diagnostics;
|
|
83
|
+
constructor(message, diagnostics) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.name = "ProtocolDesyncError";
|
|
86
|
+
this.diagnostics = diagnostics;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// src/proto/diagnostics.ts
|
|
91
|
+
var DEFAULT_BUFFER_SIZE = 32;
|
|
92
|
+
var MAX_LINE_PREVIEW = 512;
|
|
93
|
+
var ProtocolDiagnosticBuffer = class {
|
|
94
|
+
capacity;
|
|
95
|
+
entries = [];
|
|
96
|
+
constructor(capacity = DEFAULT_BUFFER_SIZE) {
|
|
97
|
+
if (capacity <= 0) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`ProtocolDiagnosticBuffer capacity must be positive, got ${capacity}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
this.capacity = capacity;
|
|
103
|
+
}
|
|
104
|
+
push(diagnostic) {
|
|
105
|
+
if (this.entries.length >= this.capacity) {
|
|
106
|
+
this.entries.shift();
|
|
107
|
+
}
|
|
108
|
+
this.entries.push(diagnostic);
|
|
109
|
+
}
|
|
110
|
+
snapshot() {
|
|
111
|
+
return this.entries.slice();
|
|
112
|
+
}
|
|
113
|
+
countWithin(windowMs, nowMs) {
|
|
114
|
+
const cutoff = nowMs - windowMs;
|
|
115
|
+
let count = 0;
|
|
116
|
+
for (let i = this.entries.length - 1; i >= 0; i -= 1) {
|
|
117
|
+
if (this.entries[i].timestampMs >= cutoff) {
|
|
118
|
+
count += 1;
|
|
119
|
+
} else {
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return count;
|
|
124
|
+
}
|
|
125
|
+
clear() {
|
|
126
|
+
this.entries.length = 0;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
function previewLine(line) {
|
|
130
|
+
if (line.length <= MAX_LINE_PREVIEW) return line;
|
|
131
|
+
return line.slice(0, MAX_LINE_PREVIEW) + "\u2026";
|
|
132
|
+
}
|
|
60
133
|
|
|
61
134
|
// src/proto/codec.ts
|
|
62
135
|
function encodeRequest(id, method, params) {
|
|
@@ -119,8 +192,8 @@ function extractId(response) {
|
|
|
119
192
|
}
|
|
120
193
|
|
|
121
194
|
// src/version.ts
|
|
122
|
-
var VERSION = "0.
|
|
123
|
-
var ENGINE_VERSION = "0.
|
|
195
|
+
var VERSION = "0.9.0";
|
|
196
|
+
var ENGINE_VERSION = "0.9.0";
|
|
124
197
|
|
|
125
198
|
// src/engine-manager.ts
|
|
126
199
|
import { spawn, execSync } from "child_process";
|
|
@@ -423,16 +496,40 @@ var EngineManager = class {
|
|
|
423
496
|
|
|
424
497
|
// src/config.ts
|
|
425
498
|
var _simulationMode = false;
|
|
499
|
+
var _sampleRate = 0;
|
|
426
500
|
function config(options) {
|
|
427
501
|
if (options.simulation !== void 0) {
|
|
428
502
|
_simulationMode = options.simulation;
|
|
429
503
|
}
|
|
504
|
+
if (options.sampleRate !== void 0) {
|
|
505
|
+
if (options.sampleRate < 0 || options.sampleRate > 1) {
|
|
506
|
+
throw new RangeError(
|
|
507
|
+
`sampleRate must be between 0.0 and 1.0, got ${options.sampleRate}`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
_sampleRate = options.sampleRate;
|
|
511
|
+
}
|
|
430
512
|
}
|
|
431
513
|
function isSimulationMode() {
|
|
432
514
|
return _simulationMode || process.env["ATTEST_SIMULATION"] === "1" || process.env["ATTEST_SIMULATION"] === "true" || process.env["ATTEST_SIMULATION"] === "yes";
|
|
433
515
|
}
|
|
516
|
+
function getSampleRate() {
|
|
517
|
+
if (_sampleRate > 0) return _sampleRate;
|
|
518
|
+
const env = process.env["ATTEST_SAMPLE_RATE"];
|
|
519
|
+
if (env !== void 0 && env !== "") {
|
|
520
|
+
const parsed = Number(env);
|
|
521
|
+
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
|
|
522
|
+
throw new RangeError(
|
|
523
|
+
`ATTEST_SAMPLE_RATE must be between 0.0 and 1.0, got '${env}'`
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
return parsed;
|
|
527
|
+
}
|
|
528
|
+
return 0;
|
|
529
|
+
}
|
|
434
530
|
function resetConfig() {
|
|
435
531
|
_simulationMode = false;
|
|
532
|
+
_sampleRate = 0;
|
|
436
533
|
}
|
|
437
534
|
|
|
438
535
|
// src/simulation.ts
|
|
@@ -448,12 +545,16 @@ function simulationEvaluateBatch(assertions) {
|
|
|
448
545
|
return {
|
|
449
546
|
results,
|
|
450
547
|
total_cost: 0,
|
|
451
|
-
total_duration_ms: 0
|
|
548
|
+
total_duration_ms: 0,
|
|
549
|
+
simulated: true
|
|
452
550
|
};
|
|
453
551
|
}
|
|
454
552
|
|
|
455
553
|
// src/client.ts
|
|
456
554
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
555
|
+
var DEFAULT_DIAGNOSTIC_BUFFER = 32;
|
|
556
|
+
var DEFAULT_DESYNC_THRESHOLD = 3;
|
|
557
|
+
var DEFAULT_DESYNC_WINDOW_MS = 1e3;
|
|
457
558
|
function resolveTimeoutMs(override) {
|
|
458
559
|
if (override !== void 0) return override;
|
|
459
560
|
const env = process.env["ATTEST_ENGINE_TIMEOUT"];
|
|
@@ -475,6 +576,24 @@ function makeTimeoutPromise(method, timeoutMs) {
|
|
|
475
576
|
}, timeoutMs);
|
|
476
577
|
});
|
|
477
578
|
}
|
|
579
|
+
function debugProtocolEnabled() {
|
|
580
|
+
const flag = process.env["ATTEST_DEBUG_PROTOCOL"];
|
|
581
|
+
return flag === "1" || flag === "true" || flag === "yes";
|
|
582
|
+
}
|
|
583
|
+
function envLoggerDefault() {
|
|
584
|
+
if (debugProtocolEnabled()) {
|
|
585
|
+
return {
|
|
586
|
+
warn: (msg, ...args) => console.warn(msg, ...args),
|
|
587
|
+
error: (msg, ...args) => console.error(msg, ...args)
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
return {
|
|
591
|
+
warn: () => {
|
|
592
|
+
},
|
|
593
|
+
error: () => {
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
}
|
|
478
597
|
var AttestClient = class {
|
|
479
598
|
engine;
|
|
480
599
|
requestId = 0;
|
|
@@ -482,8 +601,34 @@ var AttestClient = class {
|
|
|
482
601
|
writeChain = Promise.resolve();
|
|
483
602
|
readerActive = false;
|
|
484
603
|
lineHandler = null;
|
|
485
|
-
|
|
604
|
+
logger;
|
|
605
|
+
diagnosticBuffer;
|
|
606
|
+
diagnosticListeners = /* @__PURE__ */ new Set();
|
|
607
|
+
desyncThreshold;
|
|
608
|
+
desyncWindowMs;
|
|
609
|
+
desynced = false;
|
|
610
|
+
constructor(engine, options) {
|
|
486
611
|
this.engine = engine;
|
|
612
|
+
this.logger = options?.logger ?? envLoggerDefault();
|
|
613
|
+
this.diagnosticBuffer = new ProtocolDiagnosticBuffer(
|
|
614
|
+
options?.diagnosticBufferSize ?? DEFAULT_DIAGNOSTIC_BUFFER
|
|
615
|
+
);
|
|
616
|
+
this.desyncThreshold = options?.desyncThreshold ?? DEFAULT_DESYNC_THRESHOLD;
|
|
617
|
+
this.desyncWindowMs = options?.desyncWindowMs ?? DEFAULT_DESYNC_WINDOW_MS;
|
|
618
|
+
if (options?.onDiagnostic !== void 0) {
|
|
619
|
+
this.diagnosticListeners.add(options.onDiagnostic);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
/** Subscribe to protocol diagnostics. Returns an unsubscribe function. */
|
|
623
|
+
onProtocolDiagnostic(listener) {
|
|
624
|
+
this.diagnosticListeners.add(listener);
|
|
625
|
+
return () => {
|
|
626
|
+
this.diagnosticListeners.delete(listener);
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
/** Snapshot of the diagnostic ring buffer (most recent last). */
|
|
630
|
+
protocolDiagnostics() {
|
|
631
|
+
return this.diagnosticBuffer.snapshot();
|
|
487
632
|
}
|
|
488
633
|
startReader() {
|
|
489
634
|
if (this.readerActive) return;
|
|
@@ -508,35 +653,101 @@ var AttestClient = class {
|
|
|
508
653
|
this.lineHandler = null;
|
|
509
654
|
this.readerActive = false;
|
|
510
655
|
}
|
|
656
|
+
recordDiagnostic(kind, message, rawLine) {
|
|
657
|
+
const diagnostic = {
|
|
658
|
+
kind,
|
|
659
|
+
message,
|
|
660
|
+
rawLine: previewLine(rawLine),
|
|
661
|
+
timestampMs: Date.now()
|
|
662
|
+
};
|
|
663
|
+
this.diagnosticBuffer.push(diagnostic);
|
|
664
|
+
this.logger.warn(`[attest.protocol] ${kind}: ${message}`);
|
|
665
|
+
for (const listener of this.diagnosticListeners) {
|
|
666
|
+
try {
|
|
667
|
+
listener(diagnostic);
|
|
668
|
+
} catch (err) {
|
|
669
|
+
this.logger.error(
|
|
670
|
+
`[attest.protocol] diagnostic listener threw: ${err instanceof Error ? err.message : String(err)}`
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
this.maybeTriggerDesync(diagnostic.timestampMs);
|
|
675
|
+
}
|
|
676
|
+
maybeTriggerDesync(nowMs) {
|
|
677
|
+
if (this.desynced) return;
|
|
678
|
+
const recent = this.diagnosticBuffer.countWithin(this.desyncWindowMs, nowMs);
|
|
679
|
+
if (recent >= this.desyncThreshold) {
|
|
680
|
+
this.desynced = true;
|
|
681
|
+
const snapshot = this.diagnosticBuffer.snapshot();
|
|
682
|
+
const err = new ProtocolDesyncError(
|
|
683
|
+
`Engine protocol desync: ${recent} unroutable response lines within ${this.desyncWindowMs}ms.`,
|
|
684
|
+
snapshot
|
|
685
|
+
);
|
|
686
|
+
this.logger.error(`[attest.protocol] ${err.message}`);
|
|
687
|
+
this.failAll(err);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
511
690
|
handleLine(line) {
|
|
691
|
+
let response;
|
|
692
|
+
try {
|
|
693
|
+
response = decodeResponse(line);
|
|
694
|
+
} catch (err) {
|
|
695
|
+
this.handleDecodeFailure(line, err);
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
512
698
|
let reqId;
|
|
513
699
|
try {
|
|
514
|
-
const response = decodeResponse(line);
|
|
515
700
|
reqId = extractId(response);
|
|
516
|
-
const pending = this.pending.get(reqId);
|
|
517
|
-
if (pending === void 0) return;
|
|
518
|
-
this.pending.delete(reqId);
|
|
519
|
-
try {
|
|
520
|
-
const result = extractResult(response);
|
|
521
|
-
pending.resolve(result);
|
|
522
|
-
} catch (err) {
|
|
523
|
-
pending.reject(err);
|
|
524
|
-
}
|
|
525
701
|
} catch (err) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
702
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
703
|
+
this.recordDiagnostic("missing_id", message, line);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
const pending = this.pending.get(reqId);
|
|
707
|
+
if (pending === void 0) {
|
|
708
|
+
this.recordDiagnostic(
|
|
709
|
+
"unknown_id",
|
|
710
|
+
`no pending request for id=${reqId}`,
|
|
711
|
+
line
|
|
712
|
+
);
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
this.pending.delete(reqId);
|
|
716
|
+
try {
|
|
717
|
+
const result = extractResult(response);
|
|
718
|
+
pending.resolve(result);
|
|
719
|
+
} catch (err) {
|
|
720
|
+
pending.reject(err);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
handleDecodeFailure(line, err) {
|
|
724
|
+
if (err instanceof ProtocolError) {
|
|
725
|
+
let reqId = -1;
|
|
726
|
+
try {
|
|
727
|
+
const raw = JSON.parse(line.trim());
|
|
728
|
+
const idCandidate = raw["id"];
|
|
729
|
+
if (typeof idCandidate === "number" && Number.isFinite(idCandidate)) {
|
|
730
|
+
reqId = idCandidate;
|
|
537
731
|
}
|
|
732
|
+
} catch {
|
|
733
|
+
reqId = -1;
|
|
538
734
|
}
|
|
735
|
+
const pending = this.pending.get(reqId);
|
|
736
|
+
if (pending !== void 0) {
|
|
737
|
+
this.pending.delete(reqId);
|
|
738
|
+
pending.reject(err);
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
this.recordDiagnostic(
|
|
742
|
+
"non_routable_error",
|
|
743
|
+
`engine error code=${err.code} (${err.errorMessage}) had no matching pending id`,
|
|
744
|
+
line
|
|
745
|
+
);
|
|
746
|
+
return;
|
|
539
747
|
}
|
|
748
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
749
|
+
const kind = classifyDecodeError(message);
|
|
750
|
+
this.recordDiagnostic(kind, message, line);
|
|
540
751
|
}
|
|
541
752
|
failAll(err) {
|
|
542
753
|
for (const pending of this.pending.values()) {
|
|
@@ -545,6 +756,12 @@ var AttestClient = class {
|
|
|
545
756
|
this.pending.clear();
|
|
546
757
|
}
|
|
547
758
|
async sendRequest(method, params, timeoutMs) {
|
|
759
|
+
if (this.desynced) {
|
|
760
|
+
throw new ProtocolDesyncError(
|
|
761
|
+
"Engine protocol is desynced; AttestClient will not send further requests.",
|
|
762
|
+
this.diagnosticBuffer.snapshot()
|
|
763
|
+
);
|
|
764
|
+
}
|
|
548
765
|
const resolvedTimeout = resolveTimeoutMs(timeoutMs);
|
|
549
766
|
if (!this.readerActive) {
|
|
550
767
|
return Promise.race([
|
|
@@ -617,7 +834,51 @@ var AttestClient = class {
|
|
|
617
834
|
);
|
|
618
835
|
return Boolean(raw?.accepted ?? false);
|
|
619
836
|
}
|
|
837
|
+
async queryDrift(assertionId2, windowSize = 50, options) {
|
|
838
|
+
if (isSimulationMode()) {
|
|
839
|
+
return {
|
|
840
|
+
assertion_id: assertionId2,
|
|
841
|
+
mean: 1,
|
|
842
|
+
stddev: 0,
|
|
843
|
+
count: 0,
|
|
844
|
+
latest_score: 1,
|
|
845
|
+
deviation: 0,
|
|
846
|
+
status: "no_data"
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
const raw = await this.sendRequest(
|
|
850
|
+
"query_drift",
|
|
851
|
+
{ assertion_id: assertionId2, window_size: windowSize },
|
|
852
|
+
options?.timeout
|
|
853
|
+
);
|
|
854
|
+
return raw.report;
|
|
855
|
+
}
|
|
856
|
+
async generateUserMessage(persona, conversationHistory, faultConfig, options) {
|
|
857
|
+
if (isSimulationMode()) {
|
|
858
|
+
return `[simulation] Hello from ${persona.name}`;
|
|
859
|
+
}
|
|
860
|
+
const params = {
|
|
861
|
+
persona,
|
|
862
|
+
conversation_history: conversationHistory
|
|
863
|
+
};
|
|
864
|
+
if (faultConfig !== void 0) {
|
|
865
|
+
params.fault_config = faultConfig;
|
|
866
|
+
}
|
|
867
|
+
const raw = await this.sendRequest(
|
|
868
|
+
"generate_user_message",
|
|
869
|
+
params,
|
|
870
|
+
options?.timeout
|
|
871
|
+
);
|
|
872
|
+
return String(raw.message);
|
|
873
|
+
}
|
|
620
874
|
};
|
|
875
|
+
function classifyDecodeError(message) {
|
|
876
|
+
if (message.startsWith("malformed JSON")) return "malformed_json";
|
|
877
|
+
if (message.startsWith("expected JSON object")) return "non_object_response";
|
|
878
|
+
if (message.startsWith("invalid jsonrpc version")) return "invalid_jsonrpc_version";
|
|
879
|
+
if (message.startsWith("empty response line")) return "malformed_json";
|
|
880
|
+
return "malformed_json";
|
|
881
|
+
}
|
|
621
882
|
|
|
622
883
|
// src/trace.ts
|
|
623
884
|
import { randomUUID } from "crypto";
|
|
@@ -739,6 +1000,173 @@ var AgentResult = class {
|
|
|
739
1000
|
}
|
|
740
1001
|
};
|
|
741
1002
|
|
|
1003
|
+
// src/diagnostics.ts
|
|
1004
|
+
var ANSI_RESET = "\x1B[0m";
|
|
1005
|
+
var ANSI_RED = "\x1B[31m";
|
|
1006
|
+
var ANSI_YELLOW = "\x1B[33m";
|
|
1007
|
+
var ANSI_GREEN = "\x1B[32m";
|
|
1008
|
+
var ANSI_DIM = "\x1B[2m";
|
|
1009
|
+
var ANSI_BOLD = "\x1B[1m";
|
|
1010
|
+
var LAYER_NAMES = {
|
|
1011
|
+
1: "schema",
|
|
1012
|
+
2: "constraint",
|
|
1013
|
+
3: "trace",
|
|
1014
|
+
4: "content",
|
|
1015
|
+
5: "embedding",
|
|
1016
|
+
6: "llm_judge",
|
|
1017
|
+
7: "trace_tree",
|
|
1018
|
+
8: "plugin"
|
|
1019
|
+
};
|
|
1020
|
+
function layerLabel(layer, assertionType) {
|
|
1021
|
+
if (layer === 0 && assertionType) {
|
|
1022
|
+
return `L? ${assertionType}`;
|
|
1023
|
+
}
|
|
1024
|
+
const name = LAYER_NAMES[layer] ?? assertionType ?? "uncategorized";
|
|
1025
|
+
return `L${layer} ${name}`;
|
|
1026
|
+
}
|
|
1027
|
+
function statusGlyph(status, color) {
|
|
1028
|
+
let glyph;
|
|
1029
|
+
let c;
|
|
1030
|
+
if (status === STATUS_PASS) {
|
|
1031
|
+
glyph = "PASS";
|
|
1032
|
+
c = ANSI_GREEN;
|
|
1033
|
+
} else if (status === STATUS_SOFT_FAIL) {
|
|
1034
|
+
glyph = "SOFT";
|
|
1035
|
+
c = ANSI_YELLOW;
|
|
1036
|
+
} else if (status === STATUS_HARD_FAIL) {
|
|
1037
|
+
glyph = "FAIL";
|
|
1038
|
+
c = ANSI_RED;
|
|
1039
|
+
} else {
|
|
1040
|
+
glyph = status.toUpperCase() || "????";
|
|
1041
|
+
c = ANSI_DIM;
|
|
1042
|
+
}
|
|
1043
|
+
return color ? `${c}${glyph}${ANSI_RESET}` : glyph;
|
|
1044
|
+
}
|
|
1045
|
+
function bold(s, color) {
|
|
1046
|
+
return color ? `${ANSI_BOLD}${s}${ANSI_RESET}` : s;
|
|
1047
|
+
}
|
|
1048
|
+
function dim(s, color) {
|
|
1049
|
+
return color ? `${ANSI_DIM}${s}${ANSI_RESET}` : s;
|
|
1050
|
+
}
|
|
1051
|
+
function truncate(value, limit = 280) {
|
|
1052
|
+
if (value.length <= limit) {
|
|
1053
|
+
return value;
|
|
1054
|
+
}
|
|
1055
|
+
return value.slice(0, limit - 3) + "...";
|
|
1056
|
+
}
|
|
1057
|
+
function renderAssertionFailure(result, options = {}) {
|
|
1058
|
+
const color = options.color ?? false;
|
|
1059
|
+
const testFile = options.testFile;
|
|
1060
|
+
const layer = result.layer ?? 0;
|
|
1061
|
+
const label = layerLabel(layer, result.type);
|
|
1062
|
+
const lines = [];
|
|
1063
|
+
lines.push(
|
|
1064
|
+
` ${statusGlyph(result.status, color)} ${bold(result.assertion_id, color)} ${dim(`\u2014 ${label}`, color)}`
|
|
1065
|
+
);
|
|
1066
|
+
if (result.trace_node_path) {
|
|
1067
|
+
lines.push(` trace path: ${result.trace_node_path}`);
|
|
1068
|
+
}
|
|
1069
|
+
lines.push(` score: ${result.score.toFixed(3)}`);
|
|
1070
|
+
if (result.expected) {
|
|
1071
|
+
lines.push(` expected: ${truncate(result.expected)}`);
|
|
1072
|
+
}
|
|
1073
|
+
if (result.actual) {
|
|
1074
|
+
lines.push(` actual: ${truncate(result.actual)}`);
|
|
1075
|
+
}
|
|
1076
|
+
if (result.explanation) {
|
|
1077
|
+
lines.push(` detail: ${truncate(result.explanation)}`);
|
|
1078
|
+
}
|
|
1079
|
+
if (result.threshold_source && result.threshold_source !== "static") {
|
|
1080
|
+
lines.push(` threshold: ${result.threshold_source}`);
|
|
1081
|
+
}
|
|
1082
|
+
if (result.judge_metadata) {
|
|
1083
|
+
appendJudgeMetadata(lines, result.judge_metadata);
|
|
1084
|
+
}
|
|
1085
|
+
if (result.suggested_action) {
|
|
1086
|
+
lines.push(` hint: ${truncate(result.suggested_action)}`);
|
|
1087
|
+
}
|
|
1088
|
+
if ((result.cost ?? 0) > 0 || (result.duration_ms ?? 0) > 0) {
|
|
1089
|
+
const cost = result.cost ?? 0;
|
|
1090
|
+
const durMs = result.duration_ms ?? 0;
|
|
1091
|
+
lines.push(` cost/lat: $${cost.toFixed(6)} / ${durMs}ms`);
|
|
1092
|
+
}
|
|
1093
|
+
if (testFile) {
|
|
1094
|
+
lines.push(` source: ${testFile}`);
|
|
1095
|
+
}
|
|
1096
|
+
return lines.join("\n") + "\n";
|
|
1097
|
+
}
|
|
1098
|
+
function appendJudgeMetadata(lines, meta) {
|
|
1099
|
+
if (meta.model) {
|
|
1100
|
+
let rubric = meta.rubric_name ?? "default";
|
|
1101
|
+
if (meta.rubric_version) {
|
|
1102
|
+
rubric = `${rubric} @ ${meta.rubric_version}`;
|
|
1103
|
+
}
|
|
1104
|
+
lines.push(` judge: ${meta.model} / ${rubric}`);
|
|
1105
|
+
}
|
|
1106
|
+
if (meta.prompt_hash) {
|
|
1107
|
+
lines.push(` prompt: #${meta.prompt_hash}`);
|
|
1108
|
+
}
|
|
1109
|
+
const samples = meta.sample_scores ?? [];
|
|
1110
|
+
if (samples.length > 1) {
|
|
1111
|
+
const formatted = samples.map((s) => s.toFixed(2)).join(", ");
|
|
1112
|
+
const mean = (meta.score_mean ?? 0).toFixed(2);
|
|
1113
|
+
const stddev = (meta.score_stddev ?? 0).toFixed(2);
|
|
1114
|
+
const flag = meta.high_variance ? " \u26A0 HIGH VARIANCE" : "";
|
|
1115
|
+
lines.push(
|
|
1116
|
+
` samples: [${formatted}] mean=${mean} stddev=${stddev}${flag}`
|
|
1117
|
+
);
|
|
1118
|
+
}
|
|
1119
|
+
const probes = meta.bias_probes ?? [];
|
|
1120
|
+
if (probes.length > 0) {
|
|
1121
|
+
const formatted = probes.map((p) => `${p.name} \u0394${p.delta >= 0 ? "+" : ""}${p.delta.toFixed(2)}`).join(", ");
|
|
1122
|
+
lines.push(` bias: ${formatted}`);
|
|
1123
|
+
}
|
|
1124
|
+
if (meta.calibration) {
|
|
1125
|
+
const c = meta.calibration;
|
|
1126
|
+
lines.push(
|
|
1127
|
+
` calibrated: ${c.label_count} labels, agreement=${c.agreement.toFixed(2)}, \u03BA=${c.cohen_kappa.toFixed(2)}`
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
function renderSummary(result, options = {}) {
|
|
1132
|
+
const color = options.color ?? false;
|
|
1133
|
+
const passN = result.passCount;
|
|
1134
|
+
const soft = result.assertionResults.filter(
|
|
1135
|
+
(r) => r.status === STATUS_SOFT_FAIL
|
|
1136
|
+
).length;
|
|
1137
|
+
const hard = result.assertionResults.filter(
|
|
1138
|
+
(r) => r.status === STATUS_HARD_FAIL
|
|
1139
|
+
).length;
|
|
1140
|
+
const parts = [
|
|
1141
|
+
`${statusGlyph(STATUS_PASS, color)} ${passN}`,
|
|
1142
|
+
`${statusGlyph(STATUS_SOFT_FAIL, color)} ${soft}`,
|
|
1143
|
+
`${statusGlyph(STATUS_HARD_FAIL, color)} ${hard}`,
|
|
1144
|
+
`cost $${result.totalCost.toFixed(6)}`,
|
|
1145
|
+
`dur ${result.totalDurationMs}ms`
|
|
1146
|
+
];
|
|
1147
|
+
return parts.join(" | ");
|
|
1148
|
+
}
|
|
1149
|
+
function renderDiagnostics(result, options = {}) {
|
|
1150
|
+
const color = options.color ?? false;
|
|
1151
|
+
const includePassing = options.includePassing ?? false;
|
|
1152
|
+
const rows = includePassing ? result.assertionResults : result.failedAssertions;
|
|
1153
|
+
if (rows.length === 0) {
|
|
1154
|
+
return dim(" (no failures)\n", color);
|
|
1155
|
+
}
|
|
1156
|
+
const out = [""];
|
|
1157
|
+
out.push(
|
|
1158
|
+
bold(
|
|
1159
|
+
`Attest diagnostic \u2014 ${rows.length} of ${result.assertionResults.length} assertions failed:`,
|
|
1160
|
+
color
|
|
1161
|
+
)
|
|
1162
|
+
);
|
|
1163
|
+
for (const r of rows) {
|
|
1164
|
+
out.push(renderAssertionFailure(r, options));
|
|
1165
|
+
}
|
|
1166
|
+
out.push(dim(` Summary: ${renderSummary(result, { color })}`, color));
|
|
1167
|
+
return out.join("\n");
|
|
1168
|
+
}
|
|
1169
|
+
|
|
742
1170
|
// src/trace-tree.ts
|
|
743
1171
|
var TraceTree = class {
|
|
744
1172
|
root;
|
|
@@ -1943,6 +2371,260 @@ var ContinuousEvalRunner = class {
|
|
|
1943
2371
|
}
|
|
1944
2372
|
};
|
|
1945
2373
|
|
|
2374
|
+
// src/calibration.ts
|
|
2375
|
+
import { createHash as createHash2 } from "crypto";
|
|
2376
|
+
function computeAgreement(pairs, threshold) {
|
|
2377
|
+
if (pairs.length === 0) {
|
|
2378
|
+
throw new Error("no labeled pairs available");
|
|
2379
|
+
}
|
|
2380
|
+
if (threshold <= 0 || threshold >= 1) {
|
|
2381
|
+
throw new Error("threshold must be in (0, 1)");
|
|
2382
|
+
}
|
|
2383
|
+
const n = pairs.length;
|
|
2384
|
+
let humanPos = 0;
|
|
2385
|
+
let judgePos = 0;
|
|
2386
|
+
let bothPos = 0;
|
|
2387
|
+
let bothNeg = 0;
|
|
2388
|
+
for (const p of pairs) {
|
|
2389
|
+
const hPos = p.human >= threshold;
|
|
2390
|
+
const jPos = p.judge >= threshold;
|
|
2391
|
+
if (hPos) humanPos++;
|
|
2392
|
+
if (jPos) judgePos++;
|
|
2393
|
+
if (hPos && jPos) bothPos++;
|
|
2394
|
+
if (!hPos && !jPos) bothNeg++;
|
|
2395
|
+
}
|
|
2396
|
+
const humanNeg = n - humanPos;
|
|
2397
|
+
const judgeNeg = n - judgePos;
|
|
2398
|
+
const agreement = (bothPos + bothNeg) / n;
|
|
2399
|
+
const expected = (humanPos * judgePos + humanNeg * judgeNeg) / (n * n);
|
|
2400
|
+
const cohenKappa = expected < 1 ? (agreement - expected) / (1 - expected) : 0;
|
|
2401
|
+
const rocAuc = rocAUC(pairs, threshold);
|
|
2402
|
+
return { threshold, n, agreement, cohenKappa, rocAuc };
|
|
2403
|
+
}
|
|
2404
|
+
function rocAUC(pairs, threshold) {
|
|
2405
|
+
const rows = pairs.map((p) => ({
|
|
2406
|
+
score: p.judge,
|
|
2407
|
+
pos: p.human >= threshold
|
|
2408
|
+
}));
|
|
2409
|
+
const pos = rows.filter((r) => r.pos).length;
|
|
2410
|
+
const neg = rows.length - pos;
|
|
2411
|
+
if (pos === 0 || neg === 0) return 0;
|
|
2412
|
+
rows.sort((a, b) => a.score - b.score);
|
|
2413
|
+
let rankSumPos = 0;
|
|
2414
|
+
let i = 0;
|
|
2415
|
+
while (i < rows.length) {
|
|
2416
|
+
let j = i;
|
|
2417
|
+
while (j < rows.length && rows[j].score === rows[i].score) {
|
|
2418
|
+
j++;
|
|
2419
|
+
}
|
|
2420
|
+
const avgRank = (i + j + 1) / 2;
|
|
2421
|
+
for (let k = i; k < j; k++) {
|
|
2422
|
+
if (rows[k].pos) rankSumPos += avgRank;
|
|
2423
|
+
}
|
|
2424
|
+
i = j;
|
|
2425
|
+
}
|
|
2426
|
+
const auc = (rankSumPos - pos * (pos + 1) / 2) / (pos * neg);
|
|
2427
|
+
if (Number.isNaN(auc) || !Number.isFinite(auc)) return 0;
|
|
2428
|
+
return auc;
|
|
2429
|
+
}
|
|
2430
|
+
function loadLabelsCSV(text) {
|
|
2431
|
+
const rows = parseCSV(text);
|
|
2432
|
+
if (rows.length === 0) {
|
|
2433
|
+
throw new Error("empty CSV");
|
|
2434
|
+
}
|
|
2435
|
+
let start = 0;
|
|
2436
|
+
if (rows[0].length >= 2) {
|
|
2437
|
+
const firstHuman = parseFloatStrict(rows[0][1]);
|
|
2438
|
+
if (firstHuman === null) start = 1;
|
|
2439
|
+
}
|
|
2440
|
+
const out = [];
|
|
2441
|
+
for (let idx = start; idx < rows.length; idx++) {
|
|
2442
|
+
const row = rows[idx];
|
|
2443
|
+
const lineNum = idx + 1;
|
|
2444
|
+
if (row.length === 0) continue;
|
|
2445
|
+
if (row[0].trimStart().startsWith("#")) continue;
|
|
2446
|
+
if (row.length < 2) {
|
|
2447
|
+
throw new Error(
|
|
2448
|
+
`CSV line ${lineNum}: want at least 2 columns (input, human_label)`
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
const human = parseFloatStrict(row[1]);
|
|
2452
|
+
if (human === null) {
|
|
2453
|
+
throw new Error(`CSV line ${lineNum}: human_label not a float: ${row[1]}`);
|
|
2454
|
+
}
|
|
2455
|
+
const rec = {
|
|
2456
|
+
input: row[0],
|
|
2457
|
+
humanLabel: human,
|
|
2458
|
+
judgeScore: 0,
|
|
2459
|
+
judgeKnown: false
|
|
2460
|
+
};
|
|
2461
|
+
if (row.length >= 3 && row[2].trim() !== "") {
|
|
2462
|
+
const judge = parseFloatStrict(row[2]);
|
|
2463
|
+
if (judge === null) {
|
|
2464
|
+
throw new Error(
|
|
2465
|
+
`CSV line ${lineNum}: judge_score not a float: ${row[2]}`
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
rec.judgeScore = judge;
|
|
2469
|
+
rec.judgeKnown = true;
|
|
2470
|
+
}
|
|
2471
|
+
out.push(rec);
|
|
2472
|
+
}
|
|
2473
|
+
if (out.length === 0) {
|
|
2474
|
+
throw new Error("CSV contained no labeled rows");
|
|
2475
|
+
}
|
|
2476
|
+
return out;
|
|
2477
|
+
}
|
|
2478
|
+
function loadLabelsJSONL(text) {
|
|
2479
|
+
const out = [];
|
|
2480
|
+
const lines = text.split(/\r?\n/);
|
|
2481
|
+
for (let i = 0; i < lines.length; i++) {
|
|
2482
|
+
const stripped = lines[i].trim();
|
|
2483
|
+
if (!stripped) continue;
|
|
2484
|
+
let obj;
|
|
2485
|
+
try {
|
|
2486
|
+
obj = JSON.parse(stripped);
|
|
2487
|
+
} catch (err) {
|
|
2488
|
+
throw new Error(`JSONL line ${i + 1}: ${err.message}`);
|
|
2489
|
+
}
|
|
2490
|
+
if (Object.keys(obj).length === 0) continue;
|
|
2491
|
+
if (obj["human_label"] === void 0) {
|
|
2492
|
+
throw new Error(`JSONL line ${i + 1}: missing human_label`);
|
|
2493
|
+
}
|
|
2494
|
+
const human = parseJSONNumber(obj["human_label"]);
|
|
2495
|
+
if (human === null) {
|
|
2496
|
+
throw new Error(`JSONL line ${i + 1}: human_label is not a number`);
|
|
2497
|
+
}
|
|
2498
|
+
const rec = {
|
|
2499
|
+
input: typeof obj["input"] === "string" ? obj["input"] : "",
|
|
2500
|
+
humanLabel: human,
|
|
2501
|
+
judgeScore: 0,
|
|
2502
|
+
judgeKnown: false
|
|
2503
|
+
};
|
|
2504
|
+
if (obj["judge_score"] !== void 0 && obj["judge_score"] !== null) {
|
|
2505
|
+
const judge = parseJSONNumber(obj["judge_score"]);
|
|
2506
|
+
if (judge === null) {
|
|
2507
|
+
throw new Error(`JSONL line ${i + 1}: judge_score is not a number`);
|
|
2508
|
+
}
|
|
2509
|
+
rec.judgeScore = judge;
|
|
2510
|
+
rec.judgeKnown = true;
|
|
2511
|
+
}
|
|
2512
|
+
out.push(rec);
|
|
2513
|
+
}
|
|
2514
|
+
if (out.length === 0) {
|
|
2515
|
+
throw new Error("JSONL contained no labeled rows");
|
|
2516
|
+
}
|
|
2517
|
+
return out;
|
|
2518
|
+
}
|
|
2519
|
+
function promptHash(text) {
|
|
2520
|
+
return createHash2("sha256").update(text).digest("hex").slice(0, 16);
|
|
2521
|
+
}
|
|
2522
|
+
function parseFloatStrict(raw) {
|
|
2523
|
+
const trimmed = raw.trim();
|
|
2524
|
+
if (trimmed === "") return null;
|
|
2525
|
+
const n = Number(trimmed);
|
|
2526
|
+
if (Number.isNaN(n)) return null;
|
|
2527
|
+
return n;
|
|
2528
|
+
}
|
|
2529
|
+
function parseJSONNumber(value) {
|
|
2530
|
+
if (typeof value !== "number") return null;
|
|
2531
|
+
if (Number.isNaN(value)) return null;
|
|
2532
|
+
return value;
|
|
2533
|
+
}
|
|
2534
|
+
function parseCSV(text) {
|
|
2535
|
+
const rows = [];
|
|
2536
|
+
let current = [];
|
|
2537
|
+
let field = "";
|
|
2538
|
+
let inQuotes = false;
|
|
2539
|
+
let i = 0;
|
|
2540
|
+
while (i < text.length) {
|
|
2541
|
+
const ch = text[i];
|
|
2542
|
+
if (inQuotes) {
|
|
2543
|
+
if (ch === '"') {
|
|
2544
|
+
if (text[i + 1] === '"') {
|
|
2545
|
+
field += '"';
|
|
2546
|
+
i += 2;
|
|
2547
|
+
continue;
|
|
2548
|
+
}
|
|
2549
|
+
inQuotes = false;
|
|
2550
|
+
i++;
|
|
2551
|
+
continue;
|
|
2552
|
+
}
|
|
2553
|
+
field += ch;
|
|
2554
|
+
i++;
|
|
2555
|
+
continue;
|
|
2556
|
+
}
|
|
2557
|
+
if (ch === '"') {
|
|
2558
|
+
inQuotes = true;
|
|
2559
|
+
i++;
|
|
2560
|
+
continue;
|
|
2561
|
+
}
|
|
2562
|
+
if (ch === ",") {
|
|
2563
|
+
current.push(field);
|
|
2564
|
+
field = "";
|
|
2565
|
+
i++;
|
|
2566
|
+
continue;
|
|
2567
|
+
}
|
|
2568
|
+
if (ch === "\n") {
|
|
2569
|
+
current.push(field);
|
|
2570
|
+
rows.push(current);
|
|
2571
|
+
current = [];
|
|
2572
|
+
field = "";
|
|
2573
|
+
i++;
|
|
2574
|
+
continue;
|
|
2575
|
+
}
|
|
2576
|
+
if (ch === "\r") {
|
|
2577
|
+
i++;
|
|
2578
|
+
continue;
|
|
2579
|
+
}
|
|
2580
|
+
field += ch;
|
|
2581
|
+
i++;
|
|
2582
|
+
}
|
|
2583
|
+
if (field.length > 0 || current.length > 0) {
|
|
2584
|
+
current.push(field);
|
|
2585
|
+
rows.push(current);
|
|
2586
|
+
}
|
|
2587
|
+
return rows;
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
// src/personas.ts
|
|
2591
|
+
var FRIENDLY_USER = {
|
|
2592
|
+
name: "FriendlyUser",
|
|
2593
|
+
system_prompt: `You are a friendly, cooperative user interacting with an AI assistant.
|
|
2594
|
+
You make clear, well-formed requests. You respond positively to helpful answers and
|
|
2595
|
+
ask straightforward follow-up questions. Keep responses concise (1-3 sentences).`,
|
|
2596
|
+
style: "friendly",
|
|
2597
|
+
temperature: 0.7,
|
|
2598
|
+
max_tokens: 200
|
|
2599
|
+
};
|
|
2600
|
+
var ADVERSARIAL_USER = {
|
|
2601
|
+
name: "AdversarialUser",
|
|
2602
|
+
system_prompt: `You are an adversarial user testing the limits of an AI assistant.
|
|
2603
|
+
You ask edge case questions, make ambiguous requests, and probe boundary conditions.
|
|
2604
|
+
Try to find inconsistencies or unexpected behaviors. Keep responses concise (1-3 sentences).`,
|
|
2605
|
+
style: "adversarial",
|
|
2606
|
+
temperature: 0.9,
|
|
2607
|
+
max_tokens: 200
|
|
2608
|
+
};
|
|
2609
|
+
var CONFUSED_USER = {
|
|
2610
|
+
name: "ConfusedUser",
|
|
2611
|
+
system_prompt: `You are a confused user who has trouble articulating what you want.
|
|
2612
|
+
You make vague requests, sometimes contradict yourself, and frequently ask for clarification.
|
|
2613
|
+
You may misunderstand the assistant's responses. Keep responses concise (1-3 sentences).`,
|
|
2614
|
+
style: "confused",
|
|
2615
|
+
temperature: 0.8,
|
|
2616
|
+
max_tokens: 200
|
|
2617
|
+
};
|
|
2618
|
+
var COOPERATIVE_USER = {
|
|
2619
|
+
name: "CooperativeUser",
|
|
2620
|
+
system_prompt: `You are a cooperative user who actively helps the AI assistant succeed.
|
|
2621
|
+
You provide clear context, answer clarifying questions thoroughly, and confirm when
|
|
2622
|
+
the assistant's response meets your needs. Keep responses concise (1-3 sentences).`,
|
|
2623
|
+
style: "cooperative",
|
|
2624
|
+
temperature: 0.6,
|
|
2625
|
+
max_tokens: 200
|
|
2626
|
+
};
|
|
2627
|
+
|
|
1946
2628
|
// src/adapters/manual.ts
|
|
1947
2629
|
var ManualAdapter = class {
|
|
1948
2630
|
agentId;
|
|
@@ -2319,11 +3001,14 @@ var LangChainAdapter = class {
|
|
|
2319
3001
|
}
|
|
2320
3002
|
};
|
|
2321
3003
|
export {
|
|
3004
|
+
ADVERSARIAL_USER,
|
|
2322
3005
|
Agent,
|
|
2323
3006
|
AgentResult,
|
|
2324
3007
|
AlertDispatcher,
|
|
2325
3008
|
AnthropicAdapter,
|
|
2326
3009
|
AttestClient,
|
|
3010
|
+
CONFUSED_USER,
|
|
3011
|
+
COOPERATIVE_USER,
|
|
2327
3012
|
ContinuousEvalRunner,
|
|
2328
3013
|
ENGINE_VERSION,
|
|
2329
3014
|
ERR_ASSERTION_ERROR,
|
|
@@ -2335,6 +3020,7 @@ export {
|
|
|
2335
3020
|
EngineManager,
|
|
2336
3021
|
EngineTimeoutError,
|
|
2337
3022
|
ExpectChain,
|
|
3023
|
+
FRIENDLY_USER,
|
|
2338
3024
|
GeminiAdapter,
|
|
2339
3025
|
LangChainAdapter,
|
|
2340
3026
|
ManualAdapter,
|
|
@@ -2342,6 +3028,8 @@ export {
|
|
|
2342
3028
|
OllamaAdapter,
|
|
2343
3029
|
OpenAIAdapter,
|
|
2344
3030
|
PluginRegistry,
|
|
3031
|
+
ProtocolDesyncError,
|
|
3032
|
+
ProtocolDiagnosticBuffer,
|
|
2345
3033
|
ProtocolError,
|
|
2346
3034
|
STATUS_HARD_FAIL,
|
|
2347
3035
|
STATUS_PASS,
|
|
@@ -2370,6 +3058,7 @@ export {
|
|
|
2370
3058
|
agentId,
|
|
2371
3059
|
assertionId,
|
|
2372
3060
|
attestExpect,
|
|
3061
|
+
computeAgreement,
|
|
2373
3062
|
config,
|
|
2374
3063
|
decodeResponse,
|
|
2375
3064
|
delegate,
|
|
@@ -2377,8 +3066,18 @@ export {
|
|
|
2377
3066
|
executePluginAssertion,
|
|
2378
3067
|
extractId,
|
|
2379
3068
|
extractResult,
|
|
3069
|
+
getSampleRate,
|
|
2380
3070
|
isSimulationMode,
|
|
3071
|
+
layerForType,
|
|
3072
|
+
loadLabelsCSV,
|
|
3073
|
+
loadLabelsJSONL,
|
|
3074
|
+
previewLine,
|
|
3075
|
+
promptHash,
|
|
3076
|
+
renderAssertionFailure,
|
|
3077
|
+
renderDiagnostics,
|
|
3078
|
+
renderSummary,
|
|
2381
3079
|
resetConfig,
|
|
3080
|
+
simulationEvaluateBatch,
|
|
2382
3081
|
tier,
|
|
2383
3082
|
traceId
|
|
2384
3083
|
};
|