@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/cjs/index.cjs
CHANGED
|
@@ -30,11 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ADVERSARIAL_USER: () => ADVERSARIAL_USER,
|
|
33
34
|
Agent: () => Agent,
|
|
34
35
|
AgentResult: () => AgentResult,
|
|
35
36
|
AlertDispatcher: () => AlertDispatcher,
|
|
36
37
|
AnthropicAdapter: () => AnthropicAdapter,
|
|
37
38
|
AttestClient: () => AttestClient,
|
|
39
|
+
CONFUSED_USER: () => CONFUSED_USER,
|
|
40
|
+
COOPERATIVE_USER: () => COOPERATIVE_USER,
|
|
38
41
|
ContinuousEvalRunner: () => ContinuousEvalRunner,
|
|
39
42
|
ENGINE_VERSION: () => ENGINE_VERSION,
|
|
40
43
|
ERR_ASSERTION_ERROR: () => ERR_ASSERTION_ERROR,
|
|
@@ -46,6 +49,7 @@ __export(index_exports, {
|
|
|
46
49
|
EngineManager: () => EngineManager,
|
|
47
50
|
EngineTimeoutError: () => EngineTimeoutError,
|
|
48
51
|
ExpectChain: () => ExpectChain,
|
|
52
|
+
FRIENDLY_USER: () => FRIENDLY_USER,
|
|
49
53
|
GeminiAdapter: () => GeminiAdapter,
|
|
50
54
|
LangChainAdapter: () => LangChainAdapter,
|
|
51
55
|
ManualAdapter: () => ManualAdapter,
|
|
@@ -53,6 +57,8 @@ __export(index_exports, {
|
|
|
53
57
|
OllamaAdapter: () => OllamaAdapter,
|
|
54
58
|
OpenAIAdapter: () => OpenAIAdapter,
|
|
55
59
|
PluginRegistry: () => PluginRegistry,
|
|
60
|
+
ProtocolDesyncError: () => ProtocolDesyncError,
|
|
61
|
+
ProtocolDiagnosticBuffer: () => ProtocolDiagnosticBuffer,
|
|
56
62
|
ProtocolError: () => ProtocolError,
|
|
57
63
|
STATUS_HARD_FAIL: () => STATUS_HARD_FAIL,
|
|
58
64
|
STATUS_PASS: () => STATUS_PASS,
|
|
@@ -81,6 +87,7 @@ __export(index_exports, {
|
|
|
81
87
|
agentId: () => agentId,
|
|
82
88
|
assertionId: () => assertionId,
|
|
83
89
|
attestExpect: () => attestExpect,
|
|
90
|
+
computeAgreement: () => computeAgreement,
|
|
84
91
|
config: () => config,
|
|
85
92
|
decodeResponse: () => decodeResponse,
|
|
86
93
|
delegate: () => delegate,
|
|
@@ -88,8 +95,18 @@ __export(index_exports, {
|
|
|
88
95
|
executePluginAssertion: () => executePluginAssertion,
|
|
89
96
|
extractId: () => extractId,
|
|
90
97
|
extractResult: () => extractResult,
|
|
98
|
+
getSampleRate: () => getSampleRate,
|
|
91
99
|
isSimulationMode: () => isSimulationMode,
|
|
100
|
+
layerForType: () => layerForType,
|
|
101
|
+
loadLabelsCSV: () => loadLabelsCSV,
|
|
102
|
+
loadLabelsJSONL: () => loadLabelsJSONL,
|
|
103
|
+
previewLine: () => previewLine,
|
|
104
|
+
promptHash: () => promptHash,
|
|
105
|
+
renderAssertionFailure: () => renderAssertionFailure,
|
|
106
|
+
renderDiagnostics: () => renderDiagnostics,
|
|
107
|
+
renderSummary: () => renderSummary,
|
|
92
108
|
resetConfig: () => resetConfig,
|
|
109
|
+
simulationEvaluateBatch: () => simulationEvaluateBatch,
|
|
93
110
|
tier: () => tier,
|
|
94
111
|
traceId: () => traceId
|
|
95
112
|
});
|
|
@@ -128,6 +145,27 @@ function assertionId(id) {
|
|
|
128
145
|
function agentId(id) {
|
|
129
146
|
return id;
|
|
130
147
|
}
|
|
148
|
+
function layerForType(assertionType) {
|
|
149
|
+
switch (assertionType) {
|
|
150
|
+
case "schema":
|
|
151
|
+
return 1;
|
|
152
|
+
case "constraint":
|
|
153
|
+
return 2;
|
|
154
|
+
case "trace":
|
|
155
|
+
case "trace_tree":
|
|
156
|
+
return 3;
|
|
157
|
+
case "content":
|
|
158
|
+
return 4;
|
|
159
|
+
case "embedding":
|
|
160
|
+
return 5;
|
|
161
|
+
case "llm_judge":
|
|
162
|
+
return 6;
|
|
163
|
+
case "plugin":
|
|
164
|
+
return 8;
|
|
165
|
+
default:
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
131
169
|
|
|
132
170
|
// src/proto/errors.ts
|
|
133
171
|
var ProtocolError = class extends Error {
|
|
@@ -154,6 +192,58 @@ var EngineTimeoutError = class extends Error {
|
|
|
154
192
|
this.timeoutMs = timeoutMs;
|
|
155
193
|
}
|
|
156
194
|
};
|
|
195
|
+
var ProtocolDesyncError = class extends Error {
|
|
196
|
+
diagnostics;
|
|
197
|
+
constructor(message, diagnostics) {
|
|
198
|
+
super(message);
|
|
199
|
+
this.name = "ProtocolDesyncError";
|
|
200
|
+
this.diagnostics = diagnostics;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/proto/diagnostics.ts
|
|
205
|
+
var DEFAULT_BUFFER_SIZE = 32;
|
|
206
|
+
var MAX_LINE_PREVIEW = 512;
|
|
207
|
+
var ProtocolDiagnosticBuffer = class {
|
|
208
|
+
capacity;
|
|
209
|
+
entries = [];
|
|
210
|
+
constructor(capacity = DEFAULT_BUFFER_SIZE) {
|
|
211
|
+
if (capacity <= 0) {
|
|
212
|
+
throw new Error(
|
|
213
|
+
`ProtocolDiagnosticBuffer capacity must be positive, got ${capacity}`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
this.capacity = capacity;
|
|
217
|
+
}
|
|
218
|
+
push(diagnostic) {
|
|
219
|
+
if (this.entries.length >= this.capacity) {
|
|
220
|
+
this.entries.shift();
|
|
221
|
+
}
|
|
222
|
+
this.entries.push(diagnostic);
|
|
223
|
+
}
|
|
224
|
+
snapshot() {
|
|
225
|
+
return this.entries.slice();
|
|
226
|
+
}
|
|
227
|
+
countWithin(windowMs, nowMs) {
|
|
228
|
+
const cutoff = nowMs - windowMs;
|
|
229
|
+
let count = 0;
|
|
230
|
+
for (let i = this.entries.length - 1; i >= 0; i -= 1) {
|
|
231
|
+
if (this.entries[i].timestampMs >= cutoff) {
|
|
232
|
+
count += 1;
|
|
233
|
+
} else {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return count;
|
|
238
|
+
}
|
|
239
|
+
clear() {
|
|
240
|
+
this.entries.length = 0;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
function previewLine(line) {
|
|
244
|
+
if (line.length <= MAX_LINE_PREVIEW) return line;
|
|
245
|
+
return line.slice(0, MAX_LINE_PREVIEW) + "\u2026";
|
|
246
|
+
}
|
|
157
247
|
|
|
158
248
|
// src/proto/codec.ts
|
|
159
249
|
function encodeRequest(id, method, params) {
|
|
@@ -216,8 +306,8 @@ function extractId(response) {
|
|
|
216
306
|
}
|
|
217
307
|
|
|
218
308
|
// src/version.ts
|
|
219
|
-
var VERSION = "0.
|
|
220
|
-
var ENGINE_VERSION = "0.
|
|
309
|
+
var VERSION = "0.9.0";
|
|
310
|
+
var ENGINE_VERSION = "0.9.0";
|
|
221
311
|
|
|
222
312
|
// src/engine-manager.ts
|
|
223
313
|
var import_node_child_process = require("child_process");
|
|
@@ -521,16 +611,40 @@ var EngineManager = class {
|
|
|
521
611
|
|
|
522
612
|
// src/config.ts
|
|
523
613
|
var _simulationMode = false;
|
|
614
|
+
var _sampleRate = 0;
|
|
524
615
|
function config(options) {
|
|
525
616
|
if (options.simulation !== void 0) {
|
|
526
617
|
_simulationMode = options.simulation;
|
|
527
618
|
}
|
|
619
|
+
if (options.sampleRate !== void 0) {
|
|
620
|
+
if (options.sampleRate < 0 || options.sampleRate > 1) {
|
|
621
|
+
throw new RangeError(
|
|
622
|
+
`sampleRate must be between 0.0 and 1.0, got ${options.sampleRate}`
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
_sampleRate = options.sampleRate;
|
|
626
|
+
}
|
|
528
627
|
}
|
|
529
628
|
function isSimulationMode() {
|
|
530
629
|
return _simulationMode || process.env["ATTEST_SIMULATION"] === "1" || process.env["ATTEST_SIMULATION"] === "true" || process.env["ATTEST_SIMULATION"] === "yes";
|
|
531
630
|
}
|
|
631
|
+
function getSampleRate() {
|
|
632
|
+
if (_sampleRate > 0) return _sampleRate;
|
|
633
|
+
const env = process.env["ATTEST_SAMPLE_RATE"];
|
|
634
|
+
if (env !== void 0 && env !== "") {
|
|
635
|
+
const parsed = Number(env);
|
|
636
|
+
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
|
|
637
|
+
throw new RangeError(
|
|
638
|
+
`ATTEST_SAMPLE_RATE must be between 0.0 and 1.0, got '${env}'`
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
return parsed;
|
|
642
|
+
}
|
|
643
|
+
return 0;
|
|
644
|
+
}
|
|
532
645
|
function resetConfig() {
|
|
533
646
|
_simulationMode = false;
|
|
647
|
+
_sampleRate = 0;
|
|
534
648
|
}
|
|
535
649
|
|
|
536
650
|
// src/simulation.ts
|
|
@@ -546,12 +660,16 @@ function simulationEvaluateBatch(assertions) {
|
|
|
546
660
|
return {
|
|
547
661
|
results,
|
|
548
662
|
total_cost: 0,
|
|
549
|
-
total_duration_ms: 0
|
|
663
|
+
total_duration_ms: 0,
|
|
664
|
+
simulated: true
|
|
550
665
|
};
|
|
551
666
|
}
|
|
552
667
|
|
|
553
668
|
// src/client.ts
|
|
554
669
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
670
|
+
var DEFAULT_DIAGNOSTIC_BUFFER = 32;
|
|
671
|
+
var DEFAULT_DESYNC_THRESHOLD = 3;
|
|
672
|
+
var DEFAULT_DESYNC_WINDOW_MS = 1e3;
|
|
555
673
|
function resolveTimeoutMs(override) {
|
|
556
674
|
if (override !== void 0) return override;
|
|
557
675
|
const env = process.env["ATTEST_ENGINE_TIMEOUT"];
|
|
@@ -573,6 +691,24 @@ function makeTimeoutPromise(method, timeoutMs) {
|
|
|
573
691
|
}, timeoutMs);
|
|
574
692
|
});
|
|
575
693
|
}
|
|
694
|
+
function debugProtocolEnabled() {
|
|
695
|
+
const flag = process.env["ATTEST_DEBUG_PROTOCOL"];
|
|
696
|
+
return flag === "1" || flag === "true" || flag === "yes";
|
|
697
|
+
}
|
|
698
|
+
function envLoggerDefault() {
|
|
699
|
+
if (debugProtocolEnabled()) {
|
|
700
|
+
return {
|
|
701
|
+
warn: (msg, ...args) => console.warn(msg, ...args),
|
|
702
|
+
error: (msg, ...args) => console.error(msg, ...args)
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
return {
|
|
706
|
+
warn: () => {
|
|
707
|
+
},
|
|
708
|
+
error: () => {
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
}
|
|
576
712
|
var AttestClient = class {
|
|
577
713
|
engine;
|
|
578
714
|
requestId = 0;
|
|
@@ -580,8 +716,34 @@ var AttestClient = class {
|
|
|
580
716
|
writeChain = Promise.resolve();
|
|
581
717
|
readerActive = false;
|
|
582
718
|
lineHandler = null;
|
|
583
|
-
|
|
719
|
+
logger;
|
|
720
|
+
diagnosticBuffer;
|
|
721
|
+
diagnosticListeners = /* @__PURE__ */ new Set();
|
|
722
|
+
desyncThreshold;
|
|
723
|
+
desyncWindowMs;
|
|
724
|
+
desynced = false;
|
|
725
|
+
constructor(engine, options) {
|
|
584
726
|
this.engine = engine;
|
|
727
|
+
this.logger = options?.logger ?? envLoggerDefault();
|
|
728
|
+
this.diagnosticBuffer = new ProtocolDiagnosticBuffer(
|
|
729
|
+
options?.diagnosticBufferSize ?? DEFAULT_DIAGNOSTIC_BUFFER
|
|
730
|
+
);
|
|
731
|
+
this.desyncThreshold = options?.desyncThreshold ?? DEFAULT_DESYNC_THRESHOLD;
|
|
732
|
+
this.desyncWindowMs = options?.desyncWindowMs ?? DEFAULT_DESYNC_WINDOW_MS;
|
|
733
|
+
if (options?.onDiagnostic !== void 0) {
|
|
734
|
+
this.diagnosticListeners.add(options.onDiagnostic);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
/** Subscribe to protocol diagnostics. Returns an unsubscribe function. */
|
|
738
|
+
onProtocolDiagnostic(listener) {
|
|
739
|
+
this.diagnosticListeners.add(listener);
|
|
740
|
+
return () => {
|
|
741
|
+
this.diagnosticListeners.delete(listener);
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
/** Snapshot of the diagnostic ring buffer (most recent last). */
|
|
745
|
+
protocolDiagnostics() {
|
|
746
|
+
return this.diagnosticBuffer.snapshot();
|
|
585
747
|
}
|
|
586
748
|
startReader() {
|
|
587
749
|
if (this.readerActive) return;
|
|
@@ -606,35 +768,101 @@ var AttestClient = class {
|
|
|
606
768
|
this.lineHandler = null;
|
|
607
769
|
this.readerActive = false;
|
|
608
770
|
}
|
|
771
|
+
recordDiagnostic(kind, message, rawLine) {
|
|
772
|
+
const diagnostic = {
|
|
773
|
+
kind,
|
|
774
|
+
message,
|
|
775
|
+
rawLine: previewLine(rawLine),
|
|
776
|
+
timestampMs: Date.now()
|
|
777
|
+
};
|
|
778
|
+
this.diagnosticBuffer.push(diagnostic);
|
|
779
|
+
this.logger.warn(`[attest.protocol] ${kind}: ${message}`);
|
|
780
|
+
for (const listener of this.diagnosticListeners) {
|
|
781
|
+
try {
|
|
782
|
+
listener(diagnostic);
|
|
783
|
+
} catch (err) {
|
|
784
|
+
this.logger.error(
|
|
785
|
+
`[attest.protocol] diagnostic listener threw: ${err instanceof Error ? err.message : String(err)}`
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
this.maybeTriggerDesync(diagnostic.timestampMs);
|
|
790
|
+
}
|
|
791
|
+
maybeTriggerDesync(nowMs) {
|
|
792
|
+
if (this.desynced) return;
|
|
793
|
+
const recent = this.diagnosticBuffer.countWithin(this.desyncWindowMs, nowMs);
|
|
794
|
+
if (recent >= this.desyncThreshold) {
|
|
795
|
+
this.desynced = true;
|
|
796
|
+
const snapshot = this.diagnosticBuffer.snapshot();
|
|
797
|
+
const err = new ProtocolDesyncError(
|
|
798
|
+
`Engine protocol desync: ${recent} unroutable response lines within ${this.desyncWindowMs}ms.`,
|
|
799
|
+
snapshot
|
|
800
|
+
);
|
|
801
|
+
this.logger.error(`[attest.protocol] ${err.message}`);
|
|
802
|
+
this.failAll(err);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
609
805
|
handleLine(line) {
|
|
806
|
+
let response;
|
|
807
|
+
try {
|
|
808
|
+
response = decodeResponse(line);
|
|
809
|
+
} catch (err) {
|
|
810
|
+
this.handleDecodeFailure(line, err);
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
610
813
|
let reqId;
|
|
611
814
|
try {
|
|
612
|
-
const response = decodeResponse(line);
|
|
613
815
|
reqId = extractId(response);
|
|
614
|
-
const pending = this.pending.get(reqId);
|
|
615
|
-
if (pending === void 0) return;
|
|
616
|
-
this.pending.delete(reqId);
|
|
617
|
-
try {
|
|
618
|
-
const result = extractResult(response);
|
|
619
|
-
pending.resolve(result);
|
|
620
|
-
} catch (err) {
|
|
621
|
-
pending.reject(err);
|
|
622
|
-
}
|
|
623
816
|
} catch (err) {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
817
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
818
|
+
this.recordDiagnostic("missing_id", message, line);
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
const pending = this.pending.get(reqId);
|
|
822
|
+
if (pending === void 0) {
|
|
823
|
+
this.recordDiagnostic(
|
|
824
|
+
"unknown_id",
|
|
825
|
+
`no pending request for id=${reqId}`,
|
|
826
|
+
line
|
|
827
|
+
);
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
this.pending.delete(reqId);
|
|
831
|
+
try {
|
|
832
|
+
const result = extractResult(response);
|
|
833
|
+
pending.resolve(result);
|
|
834
|
+
} catch (err) {
|
|
835
|
+
pending.reject(err);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
handleDecodeFailure(line, err) {
|
|
839
|
+
if (err instanceof ProtocolError) {
|
|
840
|
+
let reqId = -1;
|
|
841
|
+
try {
|
|
842
|
+
const raw = JSON.parse(line.trim());
|
|
843
|
+
const idCandidate = raw["id"];
|
|
844
|
+
if (typeof idCandidate === "number" && Number.isFinite(idCandidate)) {
|
|
845
|
+
reqId = idCandidate;
|
|
635
846
|
}
|
|
847
|
+
} catch {
|
|
848
|
+
reqId = -1;
|
|
636
849
|
}
|
|
850
|
+
const pending = this.pending.get(reqId);
|
|
851
|
+
if (pending !== void 0) {
|
|
852
|
+
this.pending.delete(reqId);
|
|
853
|
+
pending.reject(err);
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
this.recordDiagnostic(
|
|
857
|
+
"non_routable_error",
|
|
858
|
+
`engine error code=${err.code} (${err.errorMessage}) had no matching pending id`,
|
|
859
|
+
line
|
|
860
|
+
);
|
|
861
|
+
return;
|
|
637
862
|
}
|
|
863
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
864
|
+
const kind = classifyDecodeError(message);
|
|
865
|
+
this.recordDiagnostic(kind, message, line);
|
|
638
866
|
}
|
|
639
867
|
failAll(err) {
|
|
640
868
|
for (const pending of this.pending.values()) {
|
|
@@ -643,6 +871,12 @@ var AttestClient = class {
|
|
|
643
871
|
this.pending.clear();
|
|
644
872
|
}
|
|
645
873
|
async sendRequest(method, params, timeoutMs) {
|
|
874
|
+
if (this.desynced) {
|
|
875
|
+
throw new ProtocolDesyncError(
|
|
876
|
+
"Engine protocol is desynced; AttestClient will not send further requests.",
|
|
877
|
+
this.diagnosticBuffer.snapshot()
|
|
878
|
+
);
|
|
879
|
+
}
|
|
646
880
|
const resolvedTimeout = resolveTimeoutMs(timeoutMs);
|
|
647
881
|
if (!this.readerActive) {
|
|
648
882
|
return Promise.race([
|
|
@@ -715,7 +949,51 @@ var AttestClient = class {
|
|
|
715
949
|
);
|
|
716
950
|
return Boolean(raw?.accepted ?? false);
|
|
717
951
|
}
|
|
952
|
+
async queryDrift(assertionId2, windowSize = 50, options) {
|
|
953
|
+
if (isSimulationMode()) {
|
|
954
|
+
return {
|
|
955
|
+
assertion_id: assertionId2,
|
|
956
|
+
mean: 1,
|
|
957
|
+
stddev: 0,
|
|
958
|
+
count: 0,
|
|
959
|
+
latest_score: 1,
|
|
960
|
+
deviation: 0,
|
|
961
|
+
status: "no_data"
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
const raw = await this.sendRequest(
|
|
965
|
+
"query_drift",
|
|
966
|
+
{ assertion_id: assertionId2, window_size: windowSize },
|
|
967
|
+
options?.timeout
|
|
968
|
+
);
|
|
969
|
+
return raw.report;
|
|
970
|
+
}
|
|
971
|
+
async generateUserMessage(persona, conversationHistory, faultConfig, options) {
|
|
972
|
+
if (isSimulationMode()) {
|
|
973
|
+
return `[simulation] Hello from ${persona.name}`;
|
|
974
|
+
}
|
|
975
|
+
const params = {
|
|
976
|
+
persona,
|
|
977
|
+
conversation_history: conversationHistory
|
|
978
|
+
};
|
|
979
|
+
if (faultConfig !== void 0) {
|
|
980
|
+
params.fault_config = faultConfig;
|
|
981
|
+
}
|
|
982
|
+
const raw = await this.sendRequest(
|
|
983
|
+
"generate_user_message",
|
|
984
|
+
params,
|
|
985
|
+
options?.timeout
|
|
986
|
+
);
|
|
987
|
+
return String(raw.message);
|
|
988
|
+
}
|
|
718
989
|
};
|
|
990
|
+
function classifyDecodeError(message) {
|
|
991
|
+
if (message.startsWith("malformed JSON")) return "malformed_json";
|
|
992
|
+
if (message.startsWith("expected JSON object")) return "non_object_response";
|
|
993
|
+
if (message.startsWith("invalid jsonrpc version")) return "invalid_jsonrpc_version";
|
|
994
|
+
if (message.startsWith("empty response line")) return "malformed_json";
|
|
995
|
+
return "malformed_json";
|
|
996
|
+
}
|
|
719
997
|
|
|
720
998
|
// src/trace.ts
|
|
721
999
|
var import_node_crypto = require("crypto");
|
|
@@ -837,6 +1115,173 @@ var AgentResult = class {
|
|
|
837
1115
|
}
|
|
838
1116
|
};
|
|
839
1117
|
|
|
1118
|
+
// src/diagnostics.ts
|
|
1119
|
+
var ANSI_RESET = "\x1B[0m";
|
|
1120
|
+
var ANSI_RED = "\x1B[31m";
|
|
1121
|
+
var ANSI_YELLOW = "\x1B[33m";
|
|
1122
|
+
var ANSI_GREEN = "\x1B[32m";
|
|
1123
|
+
var ANSI_DIM = "\x1B[2m";
|
|
1124
|
+
var ANSI_BOLD = "\x1B[1m";
|
|
1125
|
+
var LAYER_NAMES = {
|
|
1126
|
+
1: "schema",
|
|
1127
|
+
2: "constraint",
|
|
1128
|
+
3: "trace",
|
|
1129
|
+
4: "content",
|
|
1130
|
+
5: "embedding",
|
|
1131
|
+
6: "llm_judge",
|
|
1132
|
+
7: "trace_tree",
|
|
1133
|
+
8: "plugin"
|
|
1134
|
+
};
|
|
1135
|
+
function layerLabel(layer, assertionType) {
|
|
1136
|
+
if (layer === 0 && assertionType) {
|
|
1137
|
+
return `L? ${assertionType}`;
|
|
1138
|
+
}
|
|
1139
|
+
const name = LAYER_NAMES[layer] ?? assertionType ?? "uncategorized";
|
|
1140
|
+
return `L${layer} ${name}`;
|
|
1141
|
+
}
|
|
1142
|
+
function statusGlyph(status, color) {
|
|
1143
|
+
let glyph;
|
|
1144
|
+
let c;
|
|
1145
|
+
if (status === STATUS_PASS) {
|
|
1146
|
+
glyph = "PASS";
|
|
1147
|
+
c = ANSI_GREEN;
|
|
1148
|
+
} else if (status === STATUS_SOFT_FAIL) {
|
|
1149
|
+
glyph = "SOFT";
|
|
1150
|
+
c = ANSI_YELLOW;
|
|
1151
|
+
} else if (status === STATUS_HARD_FAIL) {
|
|
1152
|
+
glyph = "FAIL";
|
|
1153
|
+
c = ANSI_RED;
|
|
1154
|
+
} else {
|
|
1155
|
+
glyph = status.toUpperCase() || "????";
|
|
1156
|
+
c = ANSI_DIM;
|
|
1157
|
+
}
|
|
1158
|
+
return color ? `${c}${glyph}${ANSI_RESET}` : glyph;
|
|
1159
|
+
}
|
|
1160
|
+
function bold(s, color) {
|
|
1161
|
+
return color ? `${ANSI_BOLD}${s}${ANSI_RESET}` : s;
|
|
1162
|
+
}
|
|
1163
|
+
function dim(s, color) {
|
|
1164
|
+
return color ? `${ANSI_DIM}${s}${ANSI_RESET}` : s;
|
|
1165
|
+
}
|
|
1166
|
+
function truncate(value, limit = 280) {
|
|
1167
|
+
if (value.length <= limit) {
|
|
1168
|
+
return value;
|
|
1169
|
+
}
|
|
1170
|
+
return value.slice(0, limit - 3) + "...";
|
|
1171
|
+
}
|
|
1172
|
+
function renderAssertionFailure(result, options = {}) {
|
|
1173
|
+
const color = options.color ?? false;
|
|
1174
|
+
const testFile = options.testFile;
|
|
1175
|
+
const layer = result.layer ?? 0;
|
|
1176
|
+
const label = layerLabel(layer, result.type);
|
|
1177
|
+
const lines = [];
|
|
1178
|
+
lines.push(
|
|
1179
|
+
` ${statusGlyph(result.status, color)} ${bold(result.assertion_id, color)} ${dim(`\u2014 ${label}`, color)}`
|
|
1180
|
+
);
|
|
1181
|
+
if (result.trace_node_path) {
|
|
1182
|
+
lines.push(` trace path: ${result.trace_node_path}`);
|
|
1183
|
+
}
|
|
1184
|
+
lines.push(` score: ${result.score.toFixed(3)}`);
|
|
1185
|
+
if (result.expected) {
|
|
1186
|
+
lines.push(` expected: ${truncate(result.expected)}`);
|
|
1187
|
+
}
|
|
1188
|
+
if (result.actual) {
|
|
1189
|
+
lines.push(` actual: ${truncate(result.actual)}`);
|
|
1190
|
+
}
|
|
1191
|
+
if (result.explanation) {
|
|
1192
|
+
lines.push(` detail: ${truncate(result.explanation)}`);
|
|
1193
|
+
}
|
|
1194
|
+
if (result.threshold_source && result.threshold_source !== "static") {
|
|
1195
|
+
lines.push(` threshold: ${result.threshold_source}`);
|
|
1196
|
+
}
|
|
1197
|
+
if (result.judge_metadata) {
|
|
1198
|
+
appendJudgeMetadata(lines, result.judge_metadata);
|
|
1199
|
+
}
|
|
1200
|
+
if (result.suggested_action) {
|
|
1201
|
+
lines.push(` hint: ${truncate(result.suggested_action)}`);
|
|
1202
|
+
}
|
|
1203
|
+
if ((result.cost ?? 0) > 0 || (result.duration_ms ?? 0) > 0) {
|
|
1204
|
+
const cost = result.cost ?? 0;
|
|
1205
|
+
const durMs = result.duration_ms ?? 0;
|
|
1206
|
+
lines.push(` cost/lat: $${cost.toFixed(6)} / ${durMs}ms`);
|
|
1207
|
+
}
|
|
1208
|
+
if (testFile) {
|
|
1209
|
+
lines.push(` source: ${testFile}`);
|
|
1210
|
+
}
|
|
1211
|
+
return lines.join("\n") + "\n";
|
|
1212
|
+
}
|
|
1213
|
+
function appendJudgeMetadata(lines, meta) {
|
|
1214
|
+
if (meta.model) {
|
|
1215
|
+
let rubric = meta.rubric_name ?? "default";
|
|
1216
|
+
if (meta.rubric_version) {
|
|
1217
|
+
rubric = `${rubric} @ ${meta.rubric_version}`;
|
|
1218
|
+
}
|
|
1219
|
+
lines.push(` judge: ${meta.model} / ${rubric}`);
|
|
1220
|
+
}
|
|
1221
|
+
if (meta.prompt_hash) {
|
|
1222
|
+
lines.push(` prompt: #${meta.prompt_hash}`);
|
|
1223
|
+
}
|
|
1224
|
+
const samples = meta.sample_scores ?? [];
|
|
1225
|
+
if (samples.length > 1) {
|
|
1226
|
+
const formatted = samples.map((s) => s.toFixed(2)).join(", ");
|
|
1227
|
+
const mean = (meta.score_mean ?? 0).toFixed(2);
|
|
1228
|
+
const stddev = (meta.score_stddev ?? 0).toFixed(2);
|
|
1229
|
+
const flag = meta.high_variance ? " \u26A0 HIGH VARIANCE" : "";
|
|
1230
|
+
lines.push(
|
|
1231
|
+
` samples: [${formatted}] mean=${mean} stddev=${stddev}${flag}`
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
const probes = meta.bias_probes ?? [];
|
|
1235
|
+
if (probes.length > 0) {
|
|
1236
|
+
const formatted = probes.map((p) => `${p.name} \u0394${p.delta >= 0 ? "+" : ""}${p.delta.toFixed(2)}`).join(", ");
|
|
1237
|
+
lines.push(` bias: ${formatted}`);
|
|
1238
|
+
}
|
|
1239
|
+
if (meta.calibration) {
|
|
1240
|
+
const c = meta.calibration;
|
|
1241
|
+
lines.push(
|
|
1242
|
+
` calibrated: ${c.label_count} labels, agreement=${c.agreement.toFixed(2)}, \u03BA=${c.cohen_kappa.toFixed(2)}`
|
|
1243
|
+
);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
function renderSummary(result, options = {}) {
|
|
1247
|
+
const color = options.color ?? false;
|
|
1248
|
+
const passN = result.passCount;
|
|
1249
|
+
const soft = result.assertionResults.filter(
|
|
1250
|
+
(r) => r.status === STATUS_SOFT_FAIL
|
|
1251
|
+
).length;
|
|
1252
|
+
const hard = result.assertionResults.filter(
|
|
1253
|
+
(r) => r.status === STATUS_HARD_FAIL
|
|
1254
|
+
).length;
|
|
1255
|
+
const parts = [
|
|
1256
|
+
`${statusGlyph(STATUS_PASS, color)} ${passN}`,
|
|
1257
|
+
`${statusGlyph(STATUS_SOFT_FAIL, color)} ${soft}`,
|
|
1258
|
+
`${statusGlyph(STATUS_HARD_FAIL, color)} ${hard}`,
|
|
1259
|
+
`cost $${result.totalCost.toFixed(6)}`,
|
|
1260
|
+
`dur ${result.totalDurationMs}ms`
|
|
1261
|
+
];
|
|
1262
|
+
return parts.join(" | ");
|
|
1263
|
+
}
|
|
1264
|
+
function renderDiagnostics(result, options = {}) {
|
|
1265
|
+
const color = options.color ?? false;
|
|
1266
|
+
const includePassing = options.includePassing ?? false;
|
|
1267
|
+
const rows = includePassing ? result.assertionResults : result.failedAssertions;
|
|
1268
|
+
if (rows.length === 0) {
|
|
1269
|
+
return dim(" (no failures)\n", color);
|
|
1270
|
+
}
|
|
1271
|
+
const out = [""];
|
|
1272
|
+
out.push(
|
|
1273
|
+
bold(
|
|
1274
|
+
`Attest diagnostic \u2014 ${rows.length} of ${result.assertionResults.length} assertions failed:`,
|
|
1275
|
+
color
|
|
1276
|
+
)
|
|
1277
|
+
);
|
|
1278
|
+
for (const r of rows) {
|
|
1279
|
+
out.push(renderAssertionFailure(r, options));
|
|
1280
|
+
}
|
|
1281
|
+
out.push(dim(` Summary: ${renderSummary(result, { color })}`, color));
|
|
1282
|
+
return out.join("\n");
|
|
1283
|
+
}
|
|
1284
|
+
|
|
840
1285
|
// src/trace-tree.ts
|
|
841
1286
|
var TraceTree = class {
|
|
842
1287
|
root;
|
|
@@ -2041,6 +2486,260 @@ var ContinuousEvalRunner = class {
|
|
|
2041
2486
|
}
|
|
2042
2487
|
};
|
|
2043
2488
|
|
|
2489
|
+
// src/calibration.ts
|
|
2490
|
+
var import_node_crypto3 = require("crypto");
|
|
2491
|
+
function computeAgreement(pairs, threshold) {
|
|
2492
|
+
if (pairs.length === 0) {
|
|
2493
|
+
throw new Error("no labeled pairs available");
|
|
2494
|
+
}
|
|
2495
|
+
if (threshold <= 0 || threshold >= 1) {
|
|
2496
|
+
throw new Error("threshold must be in (0, 1)");
|
|
2497
|
+
}
|
|
2498
|
+
const n = pairs.length;
|
|
2499
|
+
let humanPos = 0;
|
|
2500
|
+
let judgePos = 0;
|
|
2501
|
+
let bothPos = 0;
|
|
2502
|
+
let bothNeg = 0;
|
|
2503
|
+
for (const p of pairs) {
|
|
2504
|
+
const hPos = p.human >= threshold;
|
|
2505
|
+
const jPos = p.judge >= threshold;
|
|
2506
|
+
if (hPos) humanPos++;
|
|
2507
|
+
if (jPos) judgePos++;
|
|
2508
|
+
if (hPos && jPos) bothPos++;
|
|
2509
|
+
if (!hPos && !jPos) bothNeg++;
|
|
2510
|
+
}
|
|
2511
|
+
const humanNeg = n - humanPos;
|
|
2512
|
+
const judgeNeg = n - judgePos;
|
|
2513
|
+
const agreement = (bothPos + bothNeg) / n;
|
|
2514
|
+
const expected = (humanPos * judgePos + humanNeg * judgeNeg) / (n * n);
|
|
2515
|
+
const cohenKappa = expected < 1 ? (agreement - expected) / (1 - expected) : 0;
|
|
2516
|
+
const rocAuc = rocAUC(pairs, threshold);
|
|
2517
|
+
return { threshold, n, agreement, cohenKappa, rocAuc };
|
|
2518
|
+
}
|
|
2519
|
+
function rocAUC(pairs, threshold) {
|
|
2520
|
+
const rows = pairs.map((p) => ({
|
|
2521
|
+
score: p.judge,
|
|
2522
|
+
pos: p.human >= threshold
|
|
2523
|
+
}));
|
|
2524
|
+
const pos = rows.filter((r) => r.pos).length;
|
|
2525
|
+
const neg = rows.length - pos;
|
|
2526
|
+
if (pos === 0 || neg === 0) return 0;
|
|
2527
|
+
rows.sort((a, b) => a.score - b.score);
|
|
2528
|
+
let rankSumPos = 0;
|
|
2529
|
+
let i = 0;
|
|
2530
|
+
while (i < rows.length) {
|
|
2531
|
+
let j = i;
|
|
2532
|
+
while (j < rows.length && rows[j].score === rows[i].score) {
|
|
2533
|
+
j++;
|
|
2534
|
+
}
|
|
2535
|
+
const avgRank = (i + j + 1) / 2;
|
|
2536
|
+
for (let k = i; k < j; k++) {
|
|
2537
|
+
if (rows[k].pos) rankSumPos += avgRank;
|
|
2538
|
+
}
|
|
2539
|
+
i = j;
|
|
2540
|
+
}
|
|
2541
|
+
const auc = (rankSumPos - pos * (pos + 1) / 2) / (pos * neg);
|
|
2542
|
+
if (Number.isNaN(auc) || !Number.isFinite(auc)) return 0;
|
|
2543
|
+
return auc;
|
|
2544
|
+
}
|
|
2545
|
+
function loadLabelsCSV(text) {
|
|
2546
|
+
const rows = parseCSV(text);
|
|
2547
|
+
if (rows.length === 0) {
|
|
2548
|
+
throw new Error("empty CSV");
|
|
2549
|
+
}
|
|
2550
|
+
let start = 0;
|
|
2551
|
+
if (rows[0].length >= 2) {
|
|
2552
|
+
const firstHuman = parseFloatStrict(rows[0][1]);
|
|
2553
|
+
if (firstHuman === null) start = 1;
|
|
2554
|
+
}
|
|
2555
|
+
const out = [];
|
|
2556
|
+
for (let idx = start; idx < rows.length; idx++) {
|
|
2557
|
+
const row = rows[idx];
|
|
2558
|
+
const lineNum = idx + 1;
|
|
2559
|
+
if (row.length === 0) continue;
|
|
2560
|
+
if (row[0].trimStart().startsWith("#")) continue;
|
|
2561
|
+
if (row.length < 2) {
|
|
2562
|
+
throw new Error(
|
|
2563
|
+
`CSV line ${lineNum}: want at least 2 columns (input, human_label)`
|
|
2564
|
+
);
|
|
2565
|
+
}
|
|
2566
|
+
const human = parseFloatStrict(row[1]);
|
|
2567
|
+
if (human === null) {
|
|
2568
|
+
throw new Error(`CSV line ${lineNum}: human_label not a float: ${row[1]}`);
|
|
2569
|
+
}
|
|
2570
|
+
const rec = {
|
|
2571
|
+
input: row[0],
|
|
2572
|
+
humanLabel: human,
|
|
2573
|
+
judgeScore: 0,
|
|
2574
|
+
judgeKnown: false
|
|
2575
|
+
};
|
|
2576
|
+
if (row.length >= 3 && row[2].trim() !== "") {
|
|
2577
|
+
const judge = parseFloatStrict(row[2]);
|
|
2578
|
+
if (judge === null) {
|
|
2579
|
+
throw new Error(
|
|
2580
|
+
`CSV line ${lineNum}: judge_score not a float: ${row[2]}`
|
|
2581
|
+
);
|
|
2582
|
+
}
|
|
2583
|
+
rec.judgeScore = judge;
|
|
2584
|
+
rec.judgeKnown = true;
|
|
2585
|
+
}
|
|
2586
|
+
out.push(rec);
|
|
2587
|
+
}
|
|
2588
|
+
if (out.length === 0) {
|
|
2589
|
+
throw new Error("CSV contained no labeled rows");
|
|
2590
|
+
}
|
|
2591
|
+
return out;
|
|
2592
|
+
}
|
|
2593
|
+
function loadLabelsJSONL(text) {
|
|
2594
|
+
const out = [];
|
|
2595
|
+
const lines = text.split(/\r?\n/);
|
|
2596
|
+
for (let i = 0; i < lines.length; i++) {
|
|
2597
|
+
const stripped = lines[i].trim();
|
|
2598
|
+
if (!stripped) continue;
|
|
2599
|
+
let obj;
|
|
2600
|
+
try {
|
|
2601
|
+
obj = JSON.parse(stripped);
|
|
2602
|
+
} catch (err) {
|
|
2603
|
+
throw new Error(`JSONL line ${i + 1}: ${err.message}`);
|
|
2604
|
+
}
|
|
2605
|
+
if (Object.keys(obj).length === 0) continue;
|
|
2606
|
+
if (obj["human_label"] === void 0) {
|
|
2607
|
+
throw new Error(`JSONL line ${i + 1}: missing human_label`);
|
|
2608
|
+
}
|
|
2609
|
+
const human = parseJSONNumber(obj["human_label"]);
|
|
2610
|
+
if (human === null) {
|
|
2611
|
+
throw new Error(`JSONL line ${i + 1}: human_label is not a number`);
|
|
2612
|
+
}
|
|
2613
|
+
const rec = {
|
|
2614
|
+
input: typeof obj["input"] === "string" ? obj["input"] : "",
|
|
2615
|
+
humanLabel: human,
|
|
2616
|
+
judgeScore: 0,
|
|
2617
|
+
judgeKnown: false
|
|
2618
|
+
};
|
|
2619
|
+
if (obj["judge_score"] !== void 0 && obj["judge_score"] !== null) {
|
|
2620
|
+
const judge = parseJSONNumber(obj["judge_score"]);
|
|
2621
|
+
if (judge === null) {
|
|
2622
|
+
throw new Error(`JSONL line ${i + 1}: judge_score is not a number`);
|
|
2623
|
+
}
|
|
2624
|
+
rec.judgeScore = judge;
|
|
2625
|
+
rec.judgeKnown = true;
|
|
2626
|
+
}
|
|
2627
|
+
out.push(rec);
|
|
2628
|
+
}
|
|
2629
|
+
if (out.length === 0) {
|
|
2630
|
+
throw new Error("JSONL contained no labeled rows");
|
|
2631
|
+
}
|
|
2632
|
+
return out;
|
|
2633
|
+
}
|
|
2634
|
+
function promptHash(text) {
|
|
2635
|
+
return (0, import_node_crypto3.createHash)("sha256").update(text).digest("hex").slice(0, 16);
|
|
2636
|
+
}
|
|
2637
|
+
function parseFloatStrict(raw) {
|
|
2638
|
+
const trimmed = raw.trim();
|
|
2639
|
+
if (trimmed === "") return null;
|
|
2640
|
+
const n = Number(trimmed);
|
|
2641
|
+
if (Number.isNaN(n)) return null;
|
|
2642
|
+
return n;
|
|
2643
|
+
}
|
|
2644
|
+
function parseJSONNumber(value) {
|
|
2645
|
+
if (typeof value !== "number") return null;
|
|
2646
|
+
if (Number.isNaN(value)) return null;
|
|
2647
|
+
return value;
|
|
2648
|
+
}
|
|
2649
|
+
function parseCSV(text) {
|
|
2650
|
+
const rows = [];
|
|
2651
|
+
let current = [];
|
|
2652
|
+
let field = "";
|
|
2653
|
+
let inQuotes = false;
|
|
2654
|
+
let i = 0;
|
|
2655
|
+
while (i < text.length) {
|
|
2656
|
+
const ch = text[i];
|
|
2657
|
+
if (inQuotes) {
|
|
2658
|
+
if (ch === '"') {
|
|
2659
|
+
if (text[i + 1] === '"') {
|
|
2660
|
+
field += '"';
|
|
2661
|
+
i += 2;
|
|
2662
|
+
continue;
|
|
2663
|
+
}
|
|
2664
|
+
inQuotes = false;
|
|
2665
|
+
i++;
|
|
2666
|
+
continue;
|
|
2667
|
+
}
|
|
2668
|
+
field += ch;
|
|
2669
|
+
i++;
|
|
2670
|
+
continue;
|
|
2671
|
+
}
|
|
2672
|
+
if (ch === '"') {
|
|
2673
|
+
inQuotes = true;
|
|
2674
|
+
i++;
|
|
2675
|
+
continue;
|
|
2676
|
+
}
|
|
2677
|
+
if (ch === ",") {
|
|
2678
|
+
current.push(field);
|
|
2679
|
+
field = "";
|
|
2680
|
+
i++;
|
|
2681
|
+
continue;
|
|
2682
|
+
}
|
|
2683
|
+
if (ch === "\n") {
|
|
2684
|
+
current.push(field);
|
|
2685
|
+
rows.push(current);
|
|
2686
|
+
current = [];
|
|
2687
|
+
field = "";
|
|
2688
|
+
i++;
|
|
2689
|
+
continue;
|
|
2690
|
+
}
|
|
2691
|
+
if (ch === "\r") {
|
|
2692
|
+
i++;
|
|
2693
|
+
continue;
|
|
2694
|
+
}
|
|
2695
|
+
field += ch;
|
|
2696
|
+
i++;
|
|
2697
|
+
}
|
|
2698
|
+
if (field.length > 0 || current.length > 0) {
|
|
2699
|
+
current.push(field);
|
|
2700
|
+
rows.push(current);
|
|
2701
|
+
}
|
|
2702
|
+
return rows;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
// src/personas.ts
|
|
2706
|
+
var FRIENDLY_USER = {
|
|
2707
|
+
name: "FriendlyUser",
|
|
2708
|
+
system_prompt: `You are a friendly, cooperative user interacting with an AI assistant.
|
|
2709
|
+
You make clear, well-formed requests. You respond positively to helpful answers and
|
|
2710
|
+
ask straightforward follow-up questions. Keep responses concise (1-3 sentences).`,
|
|
2711
|
+
style: "friendly",
|
|
2712
|
+
temperature: 0.7,
|
|
2713
|
+
max_tokens: 200
|
|
2714
|
+
};
|
|
2715
|
+
var ADVERSARIAL_USER = {
|
|
2716
|
+
name: "AdversarialUser",
|
|
2717
|
+
system_prompt: `You are an adversarial user testing the limits of an AI assistant.
|
|
2718
|
+
You ask edge case questions, make ambiguous requests, and probe boundary conditions.
|
|
2719
|
+
Try to find inconsistencies or unexpected behaviors. Keep responses concise (1-3 sentences).`,
|
|
2720
|
+
style: "adversarial",
|
|
2721
|
+
temperature: 0.9,
|
|
2722
|
+
max_tokens: 200
|
|
2723
|
+
};
|
|
2724
|
+
var CONFUSED_USER = {
|
|
2725
|
+
name: "ConfusedUser",
|
|
2726
|
+
system_prompt: `You are a confused user who has trouble articulating what you want.
|
|
2727
|
+
You make vague requests, sometimes contradict yourself, and frequently ask for clarification.
|
|
2728
|
+
You may misunderstand the assistant's responses. Keep responses concise (1-3 sentences).`,
|
|
2729
|
+
style: "confused",
|
|
2730
|
+
temperature: 0.8,
|
|
2731
|
+
max_tokens: 200
|
|
2732
|
+
};
|
|
2733
|
+
var COOPERATIVE_USER = {
|
|
2734
|
+
name: "CooperativeUser",
|
|
2735
|
+
system_prompt: `You are a cooperative user who actively helps the AI assistant succeed.
|
|
2736
|
+
You provide clear context, answer clarifying questions thoroughly, and confirm when
|
|
2737
|
+
the assistant's response meets your needs. Keep responses concise (1-3 sentences).`,
|
|
2738
|
+
style: "cooperative",
|
|
2739
|
+
temperature: 0.6,
|
|
2740
|
+
max_tokens: 200
|
|
2741
|
+
};
|
|
2742
|
+
|
|
2044
2743
|
// src/adapters/manual.ts
|
|
2045
2744
|
var ManualAdapter = class {
|
|
2046
2745
|
agentId;
|
|
@@ -2418,11 +3117,14 @@ var LangChainAdapter = class {
|
|
|
2418
3117
|
};
|
|
2419
3118
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2420
3119
|
0 && (module.exports = {
|
|
3120
|
+
ADVERSARIAL_USER,
|
|
2421
3121
|
Agent,
|
|
2422
3122
|
AgentResult,
|
|
2423
3123
|
AlertDispatcher,
|
|
2424
3124
|
AnthropicAdapter,
|
|
2425
3125
|
AttestClient,
|
|
3126
|
+
CONFUSED_USER,
|
|
3127
|
+
COOPERATIVE_USER,
|
|
2426
3128
|
ContinuousEvalRunner,
|
|
2427
3129
|
ENGINE_VERSION,
|
|
2428
3130
|
ERR_ASSERTION_ERROR,
|
|
@@ -2434,6 +3136,7 @@ var LangChainAdapter = class {
|
|
|
2434
3136
|
EngineManager,
|
|
2435
3137
|
EngineTimeoutError,
|
|
2436
3138
|
ExpectChain,
|
|
3139
|
+
FRIENDLY_USER,
|
|
2437
3140
|
GeminiAdapter,
|
|
2438
3141
|
LangChainAdapter,
|
|
2439
3142
|
ManualAdapter,
|
|
@@ -2441,6 +3144,8 @@ var LangChainAdapter = class {
|
|
|
2441
3144
|
OllamaAdapter,
|
|
2442
3145
|
OpenAIAdapter,
|
|
2443
3146
|
PluginRegistry,
|
|
3147
|
+
ProtocolDesyncError,
|
|
3148
|
+
ProtocolDiagnosticBuffer,
|
|
2444
3149
|
ProtocolError,
|
|
2445
3150
|
STATUS_HARD_FAIL,
|
|
2446
3151
|
STATUS_PASS,
|
|
@@ -2469,6 +3174,7 @@ var LangChainAdapter = class {
|
|
|
2469
3174
|
agentId,
|
|
2470
3175
|
assertionId,
|
|
2471
3176
|
attestExpect,
|
|
3177
|
+
computeAgreement,
|
|
2472
3178
|
config,
|
|
2473
3179
|
decodeResponse,
|
|
2474
3180
|
delegate,
|
|
@@ -2476,8 +3182,18 @@ var LangChainAdapter = class {
|
|
|
2476
3182
|
executePluginAssertion,
|
|
2477
3183
|
extractId,
|
|
2478
3184
|
extractResult,
|
|
3185
|
+
getSampleRate,
|
|
2479
3186
|
isSimulationMode,
|
|
3187
|
+
layerForType,
|
|
3188
|
+
loadLabelsCSV,
|
|
3189
|
+
loadLabelsJSONL,
|
|
3190
|
+
previewLine,
|
|
3191
|
+
promptHash,
|
|
3192
|
+
renderAssertionFailure,
|
|
3193
|
+
renderDiagnostics,
|
|
3194
|
+
renderSummary,
|
|
2480
3195
|
resetConfig,
|
|
3196
|
+
simulationEvaluateBatch,
|
|
2481
3197
|
tier,
|
|
2482
3198
|
traceId
|
|
2483
3199
|
});
|