@thinkhive/sdk 3.1.1 → 4.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/MIGRATION.md +83 -12
- package/README.md +279 -128
- package/dist/api/agents.d.ts +169 -0
- package/dist/api/agents.js +185 -0
- package/dist/api/apiKeys.d.ts +252 -0
- package/dist/api/apiKeys.js +298 -0
- package/dist/api/business-metrics.d.ts +188 -0
- package/dist/api/business-metrics.js +213 -0
- package/dist/api/calibration.d.ts +0 -62
- package/dist/api/calibration.js +5 -48
- package/dist/api/claims.js +10 -7
- package/dist/api/conversation-eval.d.ts +200 -0
- package/dist/api/conversation-eval.js +235 -0
- package/dist/api/deterministic-graders.d.ts +205 -0
- package/dist/api/deterministic-graders.js +191 -0
- package/dist/api/eval-health.d.ts +250 -0
- package/dist/api/eval-health.js +224 -0
- package/dist/api/human-review.d.ts +275 -0
- package/dist/api/human-review.js +236 -0
- package/dist/api/nondeterminism.d.ts +300 -0
- package/dist/api/nondeterminism.js +250 -0
- package/dist/api/quality-metrics.d.ts +303 -0
- package/dist/api/quality-metrics.js +198 -0
- package/dist/api/roi-analytics.d.ts +263 -0
- package/dist/api/roi-analytics.js +204 -0
- package/dist/api/runs.js +12 -6
- package/dist/api/transcript-patterns.d.ts +204 -0
- package/dist/api/transcript-patterns.js +227 -0
- package/dist/core/client.d.ts +83 -9
- package/dist/core/client.js +229 -34
- package/dist/core/config.d.ts +2 -3
- package/dist/core/config.js +3 -4
- package/dist/core/types.d.ts +57 -4
- package/dist/core/types.js +1 -1
- package/dist/index.d.ts +429 -76
- package/dist/index.js +262 -42
- package/package.json +2 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ThinkHive SDK v3.0 - Non-Determinism API
|
|
4
|
+
*
|
|
5
|
+
* API for pass@k / pass^k analysis to measure LLM evaluation reliability
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.nondeterminism = void 0;
|
|
9
|
+
exports.calculatePassAtK = calculatePassAtK;
|
|
10
|
+
exports.calculatePassToK = calculatePassToK;
|
|
11
|
+
exports.requiredPassRateForPassAtK = requiredPassRateForPassAtK;
|
|
12
|
+
exports.isReliableEvaluation = isReliableEvaluation;
|
|
13
|
+
exports.getReliabilityRecommendation = getReliabilityRecommendation;
|
|
14
|
+
const client_1 = require("../core/client");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// NON-DETERMINISM API CLIENT
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Non-Determinism API client for pass@k analysis and reliability measurement
|
|
20
|
+
*/
|
|
21
|
+
exports.nondeterminism = {
|
|
22
|
+
/**
|
|
23
|
+
* Create a new non-determinism analysis run
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const run = await nondeterminism.createRun({
|
|
28
|
+
* agentId: 'agent_123',
|
|
29
|
+
* criterionId: 'criterion_456',
|
|
30
|
+
* kValue: 5,
|
|
31
|
+
* traceIds: ['trace_1', 'trace_2', 'trace_3'],
|
|
32
|
+
* runType: 'pass_at_k',
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
async createRun(options) {
|
|
37
|
+
return (0, client_1.apiRequestWithData)('/nondeterminism/runs', {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
body: options,
|
|
40
|
+
apiVersion: 'none',
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Get non-determinism runs
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const runs = await nondeterminism.getRuns({ agentId: 'agent_123' });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
async getRuns(options = {}) {
|
|
52
|
+
const params = new URLSearchParams();
|
|
53
|
+
if (options.agentId)
|
|
54
|
+
params.set('agentId', options.agentId);
|
|
55
|
+
if (options.status)
|
|
56
|
+
params.set('status', options.status);
|
|
57
|
+
if (options.limit)
|
|
58
|
+
params.set('limit', String(options.limit));
|
|
59
|
+
if (options.offset)
|
|
60
|
+
params.set('offset', String(options.offset));
|
|
61
|
+
return (0, client_1.apiRequestWithData)(`/nondeterminism/runs?${params.toString()}`, { apiVersion: 'none' });
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Get a specific run
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const run = await nondeterminism.getRun('run_123');
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
async getRun(runId) {
|
|
72
|
+
return (0, client_1.apiRequestWithData)(`/nondeterminism/runs/${runId}`, { apiVersion: 'none' });
|
|
73
|
+
},
|
|
74
|
+
/**
|
|
75
|
+
* Start a run
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* await nondeterminism.startRun('run_123');
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
async startRun(runId) {
|
|
83
|
+
await (0, client_1.apiRequest)(`/nondeterminism/runs/${runId}/start`, {
|
|
84
|
+
method: 'POST',
|
|
85
|
+
apiVersion: 'none',
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Complete a run
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* await nondeterminism.completeRun('run_123');
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
async completeRun(runId) {
|
|
97
|
+
await (0, client_1.apiRequest)(`/nondeterminism/runs/${runId}/complete`, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
apiVersion: 'none',
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* Record a sample result
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const sample = await nondeterminism.recordSample({
|
|
108
|
+
* runId: 'run_123',
|
|
109
|
+
* traceId: 'trace_456',
|
|
110
|
+
* criterionId: 'criterion_789',
|
|
111
|
+
* sampleIndex: 0,
|
|
112
|
+
* score: 85,
|
|
113
|
+
* passed: true,
|
|
114
|
+
* reasoning: 'Response meets quality criteria',
|
|
115
|
+
* });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
async recordSample(options) {
|
|
119
|
+
return (0, client_1.apiRequestWithData)('/nondeterminism/samples', {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
body: options,
|
|
122
|
+
apiVersion: 'none',
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Get samples for a run
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const samples = await nondeterminism.getSamples('run_123');
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
async getSamples(runId) {
|
|
134
|
+
return (0, client_1.apiRequestWithData)(`/nondeterminism/runs/${runId}/samples`, { apiVersion: 'none' });
|
|
135
|
+
},
|
|
136
|
+
/**
|
|
137
|
+
* Get run summary with analysis
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const summary = await nondeterminism.getRunSummary('run_123');
|
|
142
|
+
* console.log(`Pass@k rate: ${summary.criterionAnalyses[0].passAtKRate}`);
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
async getRunSummary(runId) {
|
|
146
|
+
return (0, client_1.apiRequestWithData)(`/nondeterminism/runs/${runId}/summary`, { apiVersion: 'none' });
|
|
147
|
+
},
|
|
148
|
+
/**
|
|
149
|
+
* Trigger analysis of a completed run
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const summary = await nondeterminism.analyzeRun('run_123');
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
async analyzeRun(runId) {
|
|
157
|
+
return (0, client_1.apiRequestWithData)(`/nondeterminism/runs/${runId}/analyze`, { method: 'POST', apiVersion: 'none' });
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* Get information about pass@k analysis
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const info = await nondeterminism.getInfo();
|
|
165
|
+
* console.log(info.concepts.passAtK.description);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
async getInfo() {
|
|
169
|
+
return (0, client_1.apiRequestWithData)('/nondeterminism/info', { apiVersion: 'none' });
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// HELPER FUNCTIONS
|
|
174
|
+
// ============================================================================
|
|
175
|
+
/**
|
|
176
|
+
* Calculate pass@k probability from pass rate
|
|
177
|
+
*
|
|
178
|
+
* @param passRate - Single-run pass rate (0-1)
|
|
179
|
+
* @param k - Number of runs
|
|
180
|
+
* @returns Probability that at least 1 of k runs passes
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const passAtK = calculatePassAtK(0.7, 3); // ~0.973
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
function calculatePassAtK(passRate, k) {
|
|
188
|
+
return 1 - Math.pow(1 - passRate, k);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Calculate pass^k probability from pass rate
|
|
192
|
+
*
|
|
193
|
+
* @param passRate - Single-run pass rate (0-1)
|
|
194
|
+
* @param k - Number of runs
|
|
195
|
+
* @returns Probability that all k runs pass
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* const passToK = calculatePassToK(0.7, 3); // ~0.343
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
function calculatePassToK(passRate, k) {
|
|
203
|
+
return Math.pow(passRate, k);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Calculate required pass rate to achieve target pass@k
|
|
207
|
+
*
|
|
208
|
+
* @param targetPassAtK - Desired pass@k probability
|
|
209
|
+
* @param k - Number of runs
|
|
210
|
+
* @returns Required single-run pass rate
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const requiredRate = requiredPassRateForPassAtK(0.95, 3); // ~0.632
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
function requiredPassRateForPassAtK(targetPassAtK, k) {
|
|
218
|
+
return 1 - Math.pow(1 - targetPassAtK, 1 / k);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Determine if evaluation is reliable based on analysis
|
|
222
|
+
*
|
|
223
|
+
* @param analysis - Criterion analysis result
|
|
224
|
+
* @param reliabilityThreshold - Minimum reliability score (default 0.8)
|
|
225
|
+
* @returns Whether the evaluation is considered reliable
|
|
226
|
+
*/
|
|
227
|
+
function isReliableEvaluation(analysis, reliabilityThreshold = 0.8) {
|
|
228
|
+
return analysis.reliabilityScore >= reliabilityThreshold;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get recommendation based on reliability analysis
|
|
232
|
+
*
|
|
233
|
+
* @param analysis - Criterion analysis result
|
|
234
|
+
* @returns Actionable recommendation string
|
|
235
|
+
*/
|
|
236
|
+
function getReliabilityRecommendation(analysis) {
|
|
237
|
+
if (analysis.reliabilityScore >= 0.9) {
|
|
238
|
+
return 'Evaluation is highly reliable. No changes needed.';
|
|
239
|
+
}
|
|
240
|
+
else if (analysis.reliabilityScore >= 0.8) {
|
|
241
|
+
return 'Evaluation is reliable. Consider minor criteria refinements.';
|
|
242
|
+
}
|
|
243
|
+
else if (analysis.reliabilityScore >= 0.6) {
|
|
244
|
+
return 'Evaluation has moderate reliability. Add more specific criteria or examples.';
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
return 'Evaluation is unreliable. Consider using deterministic checks or restructuring criteria.';
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9uZGV0ZXJtaW5pc20uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL25vbmRldGVybWluaXNtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7OztHQUlHOzs7QUFxVUgsNENBRUM7QUFjRCw0Q0FFQztBQWNELGdFQUVDO0FBU0Qsb0RBS0M7QUFRRCxvRUFVQztBQXJZRCwyQ0FBZ0U7QUE0SGhFLCtFQUErRTtBQUMvRSw2QkFBNkI7QUFDN0IsK0VBQStFO0FBRS9FOztHQUVHO0FBQ1UsUUFBQSxjQUFjLEdBQUc7SUFDNUI7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBeUI7UUFDdkMsT0FBTyxJQUFBLDJCQUFrQixFQUFvQixzQkFBc0IsRUFBRTtZQUNuRSxNQUFNLEVBQUUsTUFBTTtZQUNkLElBQUksRUFBRSxPQUFPO1lBQ2IsVUFBVSxFQUFFLE1BQU07U0FDbkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQTJCLEVBQUU7UUFDekMsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNyQyxJQUFJLE9BQU8sQ0FBQyxPQUFPO1lBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVELElBQUksT0FBTyxDQUFDLE1BQU07WUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekQsSUFBSSxPQUFPLENBQUMsS0FBSztZQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM5RCxJQUFJLE9BQU8sQ0FBQyxNQUFNO1lBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFD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QUcsYUFBYSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0Isb0JBQW9CLENBQ2xDLFFBQTJCLEVBQzNCLG9CQUFvQixHQUFHLEdBQUc7SUFFMUIsT0FBTyxRQUFRLENBQUMsZ0JBQWdCLElBQUksb0JBQW9CLENBQUM7QUFDM0QsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsNEJBQTRCLENBQUMsUUFBMkI7SUFDdEUsSUFBSSxRQUFRLENBQUMsZ0JBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDckMsT0FBTyxtREFBbUQsQ0FBQztJQUM3RCxDQUFDO1NBQU0sSUFBSSxRQUFRLENBQUMsZ0JBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDNUMsT0FBTyw4REFBOEQsQ0FBQztJQUN4RSxDQUFDO1NBQU0sSUFBSSxRQUFRLENBQUMsZ0JBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDNUMsT0FBTyw4RUFBOEUsQ0FBQztJQUN4RixDQUFDO1NBQU0sQ0FBQztRQUNOLE9BQU8sMEZBQTBGLENBQUM7SUFDcEcsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaW5rSGl2ZSBTREsgdjMuMCAtIE5vbi1EZXRlcm1pbmlzbSBBUElcbiAqXG4gKiBBUEkgZm9yIHBhc3NAayAvIHBhc3NeayBhbmFseXNpcyB0byBtZWFzdXJlIExMTSBldmFsdWF0aW9uIHJlbGlhYmlsaXR5XG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdCwgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgdHlwZSBOb25kZXRlcm1pbmlzbVJ1blR5cGUgPSAncGFzc19hdF9rJyB8ICdwYXNzX3RvX2snIHwgJ3ZhcmlhbmNlJyB8ICdyZWxpYWJpbGl0eSc7XG5leHBvcnQgdHlwZSBOb25kZXRlcm1pbmlzbVJ1blN0YXR1cyA9ICdwZW5kaW5nJyB8ICdydW5uaW5nJyB8ICdjb21wbGV0ZWQnIHwgJ2ZhaWxlZCcgfCAnY2FuY2VsbGVkJztcblxuZXhwb3J0IGludGVyZmFjZSBOb25kZXRlcm1pbmlzbVJ1biB7XG4gIGlkOiBzdHJpbmc7XG4gIGNvbXBhbnlJZDogc3RyaW5nO1xuICBhZ2VudElkOiBzdHJpbmc7XG4gIHJ1blR5cGU6IE5vbmRldGVybWluaXNtUnVuVHlwZTtcbiAga1ZhbHVlOiBudW1iZXI7XG4gIHN0YXR1czogTm9uZGV0ZXJtaW5pc21SdW5TdGF0dXM7XG4gIHRyYWNlQ291bnQ6IG51bWJlcjtcbiAgY3JpdGVyaW9uSWQ/OiBzdHJpbmc7XG4gIGNyaXRlcmlhSWRzOiBzdHJpbmdbXTtcbiAgdGVtcGVyYXR1cmU/OiBzdHJpbmc7XG4gIG1vZGVsPzogc3RyaW5nO1xuICBwcm9ncmVzc1BlcmNlbnQ6IG51bWJlcjtcbiAgcGFzc0F0S1JhdGU/OiBzdHJpbmc7XG4gIHBhc3NUb0tSYXRlPzogc3RyaW5nO1xuICBhdmdWYXJpYW5jZT86IHN0cmluZztcbiAgcmVsaWFiaWxpdHlTY29yZT86IHN0cmluZztcbiAgc3RhcnRlZEF0Pzogc3RyaW5nO1xuICBjb21wbGV0ZWRBdD86IHN0cmluZztcbiAgY3JlYXRlZEJ5Pzogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOb25kZXRlcm1pbmlzbVNhbXBsZSB7XG4gIGlkOiBzdHJpbmc7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ6IHN0cmluZztcbiAgc2FtcGxlSW5kZXg6IG51bWJlcjtcbiAgc2NvcmU6IHN0cmluZztcbiAgcGFzc2VkOiBib29sZWFuO1xuICByZWFzb25pbmc/OiBzdHJpbmc7XG4gIGNvbmZpZGVuY2U/OiBzdHJpbmc7XG4gIHRva2Vuc1VzZWQ/OiBudW1iZXI7XG4gIGNvc3RVc2Q/OiBzdHJpbmc7XG4gIG1vZGVsPzogc3RyaW5nO1xuICB0ZW1wZXJhdHVyZT86IHN0cmluZztcbiAgbGF0ZW5jeU1zPzogbnVtYmVyO1xuICBlcnJvcj86IHN0cmluZztcbiAgY3JlYXRlZEF0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlUnVuT3B0aW9ucyB7XG4gIGFnZW50SWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ/OiBzdHJpbmc7XG4gIGNyaXRlcmlhSWRzPzogc3RyaW5nW107XG4gIGtWYWx1ZTogbnVtYmVyO1xuICB0cmFjZUlkczogc3RyaW5nW107XG4gIHJ1blR5cGU/OiBOb25kZXRlcm1pbmlzbVJ1blR5cGU7XG4gIHRlbXBlcmF0dXJlPzogbnVtYmVyO1xuICBtb2RlbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvcmRTYW1wbGVPcHRpb25zIHtcbiAgcnVuSWQ6IHN0cmluZztcbiAgdHJhY2VJZDogc3RyaW5nO1xuICBjcml0ZXJpb25JZDogc3RyaW5nO1xuICBzYW1wbGVJbmRleDogbnVtYmVyO1xuICBzY29yZTogbnVtYmVyO1xuICBwYXNzZWQ6IGJvb2xlYW47XG4gIHJlYXNvbmluZz86IHN0cmluZztcbiAgY29uZmlkZW5jZT86IG51bWJlcjtcbiAgdG9rZW5zVXNlZD86IG51bWJlcjtcbiAgY29zdFVzZD86IG51bWJlcjtcbiAgbW9kZWw/OiBzdHJpbmc7XG4gIHRlbXBlcmF0dXJlPzogbnVtYmVyO1xuICBsYXRlbmN5TXM/OiBudW1iZXI7XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWNlQW5hbHlzaXMge1xuICB0cmFjZUlkOiBzdHJpbmc7XG4gIHNhbXBsZXM6IE5vbmRldGVybWluaXNtU2FtcGxlW107XG4gIHBhc3NDb3VudDogbnVtYmVyO1xuICB0b3RhbENvdW50OiBudW1iZXI7XG4gIHBhc3NSYXRlOiBudW1iZXI7XG4gIHNjb3JlVmFyaWFuY2U6IG51bWJlcjtcbiAgbWVhblNjb3JlOiBudW1iZXI7XG4gIGlzQ29uc2lzdGVudDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcml0ZXJpb25BbmFseXNpcyB7XG4gIGNyaXRlcmlvbklkOiBzdHJpbmc7XG4gIHRyYWNlQW5hbHlzZXM6IFRyYWNlQW5hbHlzaXNbXTtcbiAgcGFzc0F0S1JhdGU6IG51bWJlcjtcbiAgcGFzc1RvS1JhdGU6IG51bWJlcjtcbiAgcmVsaWFiaWxpdHlTY29yZTogbnVtYmVyO1xuICBpc1JlbGlhYmxlOiBib29sZWFuO1xuICByZWNvbW1lbmRhdGlvbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1blN1bW1hcnkge1xuICBydW46IE5vbmRldGVybWluaXNtUnVuO1xuICB0cmFjZUFuYWx5c2VzOiBUcmFjZUFuYWx5c2lzW107XG4gIGNyaXRlcmlvbkFuYWx5c2VzOiBDcml0ZXJpb25BbmFseXNpc1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RSdW5zT3B0aW9ucyB7XG4gIGFnZW50SWQ/OiBzdHJpbmc7XG4gIHN0YXR1cz86IE5vbmRldGVybWluaXNtUnVuU3RhdHVzO1xuICBsaW1pdD86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhc3NBdEtJbmZvIHtcbiAgY29uY2VwdHM6IHtcbiAgICBwYXNzQXRLOiB7IG5hbWU6IHN0cmluZzsgZGVzY3JpcHRpb246IHN0cmluZzsgZm9ybXVsYTogc3RyaW5nOyB1c2VDYXNlOiBzdHJpbmcgfTtcbiAgICBwYXNzVG9LOiB7IG5hbWU6IHN0cmluZzsgZGVzY3JpcHRpb246IHN0cmluZzsgZm9ybXVsYTogc3RyaW5nOyB1c2VDYXNlOiBzdHJpbmcgfTtcbiAgICB2YXJpYW5jZTogeyBuYW1lOiBzdHJpbmc7IGRlc2NyaXB0aW9uOiBzdHJpbmc7IHVzZUNhc2U6IHN0cmluZyB9O1xuICAgIHJlbGlhYmlsaXR5OiB7IG5hbWU6IHN0cmluZzsgZGVzY3JpcHRpb246IHN0cmluZzsgdXNlQ2FzZTogc3RyaW5nIH07XG4gIH07XG4gIHJlY29tbWVuZGF0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgZGVmYXVsdHM6IHsga1ZhbHVlOiBudW1iZXI7IHJlbGlhYmlsaXR5VGhyZXNob2xkOiBudW1iZXI7IHZhcmlhbmNlVGhyZXNob2xkOiBudW1iZXIgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gTk9OLURFVEVSTUlOSVNNIEFQSSBDTElFTlRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBOb24tRGV0ZXJtaW5pc20gQVBJIGNsaWVudCBmb3IgcGFzc0BrIGFuYWx5c2lzIGFuZCByZWxpYWJpbGl0eSBtZWFzdXJlbWVudFxuICovXG5leHBvcnQgY29uc3Qgbm9uZGV0ZXJtaW5pc20gPSB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgbm9uLWRldGVybWluaXNtIGFuYWx5c2lzIHJ1blxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJ1biA9IGF3YWl0IG5vbmRldGVybWluaXNtLmNyZWF0ZVJ1bih7XG4gICAqICAgYWdlbnRJZDogJ2FnZW50XzEyMycsXG4gICAqICAgY3JpdGVyaW9uSWQ6ICdjcml0ZXJpb25fNDU2JyxcbiAgICogICBrVmFsdWU6IDUsXG4gICAqICAgdHJhY2VJZHM6IFsndHJhY2VfMScsICd0cmFjZV8yJywgJ3RyYWNlXzMnXSxcbiAgICogICBydW5UeXBlOiAncGFzc19hdF9rJyxcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgY3JlYXRlUnVuKG9wdGlvbnM6IENyZWF0ZVJ1bk9wdGlvbnMpOiBQcm9taXNlPE5vbmRldGVybWluaXNtUnVuPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxOb25kZXRlcm1pbmlzbVJ1bj4oJy9ub25kZXRlcm1pbmlzbS9ydW5zJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgYXBpVmVyc2lvbjogJ25vbmUnLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgbm9uLWRldGVybWluaXNtIHJ1bnNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBydW5zID0gYXdhaXQgbm9uZGV0ZXJtaW5pc20uZ2V0UnVucyh7IGFnZW50SWQ6ICdhZ2VudF8xMjMnIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldFJ1bnMob3B0aW9uczogTGlzdFJ1bnNPcHRpb25zID0ge30pOiBQcm9taXNlPE5vbmRldGVybWluaXNtUnVuW10+IHtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgaWYgKG9wdGlvbnMuYWdlbnRJZCkgcGFyYW1zLnNldCgnYWdlbnRJZCcsIG9wdGlvbnMuYWdlbnRJZCk7XG4gICAgaWYgKG9wdGlvbnMuc3RhdHVzKSBwYXJhbXMuc2V0KCdzdGF0dXMnLCBvcHRpb25zLnN0YXR1cyk7XG4gICAgaWYgKG9wdGlvbnMubGltaXQpIHBhcmFtcy5zZXQoJ2xpbWl0JywgU3RyaW5nKG9wdGlvbnMubGltaXQpKTtcbiAgICBpZiAob3B0aW9ucy5vZmZzZXQpIHBhcmFtcy5zZXQoJ29mZnNldCcsIFN0cmluZyhvcHRpb25zLm9mZnNldCkpO1xuXG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxOb25kZXRlcm1pbmlzbVJ1bltdPihcbiAgICAgIGAvbm9uZGV0ZXJtaW5pc20vcnVucz8ke3BhcmFtcy50b1N0cmluZygpfWAsXG4gICAgICB7IGFwaVZlcnNpb246ICdub25lJyB9XG4gICAgKTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGEgc3BlY2lmaWMgcnVuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgcnVuID0gYXdhaXQgbm9uZGV0ZXJtaW5pc20uZ2V0UnVuKCdydW5fMTIzJyk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0UnVuKHJ1bklkOiBzdHJpbmcpOiBQcm9taXNlPE5vbmRldGVybWluaXNtUnVuPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxOb25kZXRlcm1pbmlzbVJ1bj4oXG4gICAgICBgL25vbmRldGVybWluaXNtL3J1bnMvJHtydW5JZH1gLFxuICAgICAgeyBhcGlWZXJzaW9uOiAnbm9uZScgfVxuICAgICk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgcnVuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogYXdhaXQgbm9uZGV0ZXJtaW5pc20uc3RhcnRSdW4oJ3J1bl8xMjMnKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBzdGFydFJ1bihydW5JZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgYXBpUmVxdWVzdChgL25vbmRldGVybWluaXNtL3J1bnMvJHtydW5JZH0vc3RhcnRgLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGFwaVZlcnNpb246ICdub25lJyxcbiAgICB9KTtcbiAgfSxcblxuICAvKipcbiAgICogQ29tcGxldGUgYSBydW5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBhd2FpdCBub25kZXRlcm1pbmlzbS5jb21wbGV0ZVJ1bigncnVuXzEyMycpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGNvbXBsZXRlUnVuKHJ1bklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBhcGlSZXF1ZXN0KGAvbm9uZGV0ZXJtaW5pc20vcnVucy8ke3J1bklkfS9jb21wbGV0ZWAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYXBpVmVyc2lvbjogJ25vbmUnLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYSBzYW1wbGUgcmVzdWx0XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3Qgc2FtcGxlID0gYXdhaXQgbm9uZGV0ZXJtaW5pc20ucmVjb3JkU2FtcGxlKHtcbiAgICogICBydW5JZDogJ3J1bl8xMjMnLFxuICAgKiAgIHRyYWNlSWQ6ICd0cmFjZV80NTYnLFxuICAgKiAgIGNyaXRlcmlvbklkOiAnY3JpdGVyaW9uXzc4OScsXG4gICAqICAgc2FtcGxlSW5kZXg6IDAsXG4gICAqICAgc2NvcmU6IDg1LFxuICAgKiAgIHBhc3NlZDogdHJ1ZSxcbiAgICogICByZWFzb25pbmc6ICdSZXNwb25zZSBtZWV0cyBxdWFsaXR5IGNyaXRlcmlhJyxcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgcmVjb3JkU2FtcGxlKG9wdGlvbnM6IFJlY29yZFNhbXBsZU9wdGlvbnMpOiBQcm9taXNlPE5vbmRldGVybWluaXNtU2FtcGxlPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxOb25kZXRlcm1pbmlzbVNhbXBsZT4oJy9ub25kZXRlcm1pbmlzbS9zYW1wbGVzJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgYXBpVmVyc2lvbjogJ25vbmUnLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgc2FtcGxlcyBmb3IgYSBydW5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBzYW1wbGVzID0gYXdhaXQgbm9uZGV0ZXJtaW5pc20uZ2V0U2FtcGxlcygncnVuXzEyMycpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldFNhbXBsZXMocnVuSWQ6IHN0cmluZyk6IFByb21pc2U8Tm9uZGV0ZXJtaW5pc21TYW1wbGVbXT4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8Tm9uZGV0ZXJtaW5pc21TYW1wbGVbXT4oXG4gICAgICBgL25vbmRldGVybWluaXNtL3J1bnMvJHtydW5JZH0vc2FtcGxlc2AsXG4gICAgICB7IGFwaVZlcnNpb246ICdub25lJyB9XG4gICAgKTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IHJ1biBzdW1tYXJ5IHdpdGggYW5hbHlzaXNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBzdW1tYXJ5ID0gYXdhaXQgbm9uZGV0ZXJtaW5pc20uZ2V0UnVuU3VtbWFyeSgncnVuXzEyMycpO1xuICAgKiBjb25zb2xlLmxvZyhgUGFzc0BrIHJhdGU6ICR7c3VtbWFyeS5jcml0ZXJpb25BbmFseXNlc1swXS5wYXNzQXRLUmF0ZX1gKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBnZXRSdW5TdW1tYXJ5KHJ1bklkOiBzdHJpbmcpOiBQcm9taXNlPFJ1blN1bW1hcnk+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPFJ1blN1bW1hcnk+KFxuICAgICAgYC9ub25kZXRlcm1pbmlzbS9ydW5zLyR7cnVuSWR9L3N1bW1hcnlgLFxuICAgICAgeyBhcGlWZXJzaW9uOiAnbm9uZScgfVxuICAgICk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFRyaWdnZXIgYW5hbHlzaXMgb2YgYSBjb21wbGV0ZWQgcnVuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3Qgc3VtbWFyeSA9IGF3YWl0IG5vbmRldGVybWluaXNtLmFuYWx5emVSdW4oJ3J1bl8xMjMnKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBhbmFseXplUnVuKHJ1bklkOiBzdHJpbmcpOiBQcm9taXNlPFJ1blN1bW1hcnk+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPFJ1blN1bW1hcnk+KFxuICAgICAgYC9ub25kZXRlcm1pbmlzbS9ydW5zLyR7cnVuSWR9L2FuYWx5emVgLFxuICAgICAgeyBtZXRob2Q6ICdQT1NUJywgYXBpVmVyc2lvbjogJ25vbmUnIH1cbiAgICApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgcGFzc0BrIGFuYWx5c2lzXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgaW5mbyA9IGF3YWl0IG5vbmRldGVybWluaXNtLmdldEluZm8oKTtcbiAgICogY29uc29sZS5sb2coaW5mby5jb25jZXB0cy5wYXNzQXRLLmRlc2NyaXB0aW9uKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBnZXRJbmZvKCk6IFByb21pc2U8UGFzc0F0S0luZm8+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPFBhc3NBdEtJbmZvPihcbiAgICAgICcvbm9uZGV0ZXJtaW5pc20vaW5mbycsXG4gICAgICB7IGFwaVZlcnNpb246ICdub25lJyB9XG4gICAgKTtcbiAgfSxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDYWxjdWxhdGUgcGFzc0BrIHByb2JhYmlsaXR5IGZyb20gcGFzcyByYXRlXG4gKlxuICogQHBhcmFtIHBhc3NSYXRlIC0gU2luZ2xlLXJ1biBwYXNzIHJhdGUgKDAtMSlcbiAqIEBwYXJhbSBrIC0gTnVtYmVyIG9mIHJ1bnNcbiAqIEByZXR1cm5zIFByb2JhYmlsaXR5IHRoYXQgYXQgbGVhc3QgMSBvZiBrIHJ1bnMgcGFzc2VzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHBhc3NBdEsgPSBjYWxjdWxhdGVQYXNzQXRLKDAuNywgMyk7IC8vIH4wLjk3M1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVQYXNzQXRLKHBhc3NSYXRlOiBudW1iZXIsIGs6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiAxIC0gTWF0aC5wb3coMSAtIHBhc3NSYXRlLCBrKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgcGFzc15rIHByb2JhYmlsaXR5IGZyb20gcGFzcyByYXRlXG4gKlxuICogQHBhcmFtIHBhc3NSYXRlIC0gU2luZ2xlLXJ1biBwYXNzIHJhdGUgKDAtMSlcbiAqIEBwYXJhbSBrIC0gTnVtYmVyIG9mIHJ1bnNcbiAqIEByZXR1cm5zIFByb2JhYmlsaXR5IHRoYXQgYWxsIGsgcnVucyBwYXNzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHBhc3NUb0sgPSBjYWxjdWxhdGVQYXNzVG9LKDAuNywgMyk7IC8vIH4wLjM0M1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVQYXNzVG9LKHBhc3NSYXRlOiBudW1iZXIsIGs6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnBvdyhwYXNzUmF0ZSwgayk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHJlcXVpcmVkIHBhc3MgcmF0ZSB0byBhY2hpZXZlIHRhcmdldCBwYXNzQGtcbiAqXG4gKiBAcGFyYW0gdGFyZ2V0UGFzc0F0SyAtIERlc2lyZWQgcGFzc0BrIHByb2JhYmlsaXR5XG4gKiBAcGFyYW0gayAtIE51bWJlciBvZiBydW5zXG4gKiBAcmV0dXJucyBSZXF1aXJlZCBzaW5nbGUtcnVuIHBhc3MgcmF0ZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXF1aXJlZFJhdGUgPSByZXF1aXJlZFBhc3NSYXRlRm9yUGFzc0F0SygwLjk1LCAzKTsgLy8gfjAuNjMyXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVkUGFzc1JhdGVGb3JQYXNzQXRLKHRhcmdldFBhc3NBdEs6IG51bWJlciwgazogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIDEgLSBNYXRoLnBvdygxIC0gdGFyZ2V0UGFzc0F0SywgMSAvIGspO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBldmFsdWF0aW9uIGlzIHJlbGlhYmxlIGJhc2VkIG9uIGFuYWx5c2lzXG4gKlxuICogQHBhcmFtIGFuYWx5c2lzIC0gQ3JpdGVyaW9uIGFuYWx5c2lzIHJlc3VsdFxuICogQHBhcmFtIHJlbGlhYmlsaXR5VGhyZXNob2xkIC0gTWluaW11bSByZWxpYWJpbGl0eSBzY29yZSAoZGVmYXVsdCAwLjgpXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBldmFsdWF0aW9uIGlzIGNvbnNpZGVyZWQgcmVsaWFibGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmVsaWFibGVFdmFsdWF0aW9uKFxuICBhbmFseXNpczogQ3JpdGVyaW9uQW5hbHlzaXMsXG4gIHJlbGlhYmlsaXR5VGhyZXNob2xkID0gMC44XG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGFuYWx5c2lzLnJlbGlhYmlsaXR5U2NvcmUgPj0gcmVsaWFiaWxpdHlUaHJlc2hvbGQ7XG59XG5cbi8qKlxuICogR2V0IHJlY29tbWVuZGF0aW9uIGJhc2VkIG9uIHJlbGlhYmlsaXR5IGFuYWx5c2lzXG4gKlxuICogQHBhcmFtIGFuYWx5c2lzIC0gQ3JpdGVyaW9uIGFuYWx5c2lzIHJlc3VsdFxuICogQHJldHVybnMgQWN0aW9uYWJsZSByZWNvbW1lbmRhdGlvbiBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlbGlhYmlsaXR5UmVjb21tZW5kYXRpb24oYW5hbHlzaXM6IENyaXRlcmlvbkFuYWx5c2lzKTogc3RyaW5nIHtcbiAgaWYgKGFuYWx5c2lzLnJlbGlhYmlsaXR5U2NvcmUgPj0gMC45KSB7XG4gICAgcmV0dXJuICdFdmFsdWF0aW9uIGlzIGhpZ2hseSByZWxpYWJsZS4gTm8gY2hhbmdlcyBuZWVkZWQuJztcbiAgfSBlbHNlIGlmIChhbmFseXNpcy5yZWxpYWJpbGl0eVNjb3JlID49IDAuOCkge1xuICAgIHJldHVybiAnRXZhbHVhdGlvbiBpcyByZWxpYWJsZS4gQ29uc2lkZXIgbWlub3IgY3JpdGVyaWEgcmVmaW5lbWVudHMuJztcbiAgfSBlbHNlIGlmIChhbmFseXNpcy5yZWxpYWJpbGl0eVNjb3JlID49IDAuNikge1xuICAgIHJldHVybiAnRXZhbHVhdGlvbiBoYXMgbW9kZXJhdGUgcmVsaWFiaWxpdHkuIEFkZCBtb3JlIHNwZWNpZmljIGNyaXRlcmlhIG9yIGV4YW1wbGVzLic7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICdFdmFsdWF0aW9uIGlzIHVucmVsaWFibGUuIENvbnNpZGVyIHVzaW5nIGRldGVybWluaXN0aWMgY2hlY2tzIG9yIHJlc3RydWN0dXJpbmcgY3JpdGVyaWEuJztcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThinkHive SDK v3.1 - Quality Metrics API
|
|
3
|
+
*
|
|
4
|
+
* RAG Evaluation & Hallucination Detection for AI quality assurance
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Retrieved context for RAG evaluation
|
|
8
|
+
*/
|
|
9
|
+
export interface RetrievedContext {
|
|
10
|
+
content: string;
|
|
11
|
+
chunkIndex?: number;
|
|
12
|
+
metadata?: Record<string, unknown>;
|
|
13
|
+
score?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Ground truth context
|
|
17
|
+
*/
|
|
18
|
+
export interface GroundTruthContext {
|
|
19
|
+
content: string;
|
|
20
|
+
chunkIndex?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Grounded span evidence
|
|
24
|
+
*/
|
|
25
|
+
export interface GroundedSpan {
|
|
26
|
+
text: string;
|
|
27
|
+
confidence: number;
|
|
28
|
+
sourceChunkIndex?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Ungrounded span evidence
|
|
32
|
+
*/
|
|
33
|
+
export interface UngroundedSpan {
|
|
34
|
+
text: string;
|
|
35
|
+
confidence: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Citation mapping
|
|
39
|
+
*/
|
|
40
|
+
export interface CitationMap {
|
|
41
|
+
claim: string;
|
|
42
|
+
citedIndex: number;
|
|
43
|
+
isValid: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* RAG evaluation result
|
|
47
|
+
*/
|
|
48
|
+
export interface RAGEvaluation {
|
|
49
|
+
contextRelevance: number;
|
|
50
|
+
contextPrecision: number;
|
|
51
|
+
contextRecall: number;
|
|
52
|
+
groundedness: number;
|
|
53
|
+
faithfulness: number;
|
|
54
|
+
answerRelevance: number;
|
|
55
|
+
citationAccuracy: number;
|
|
56
|
+
citationCompleteness: number;
|
|
57
|
+
overallScore: number;
|
|
58
|
+
grade: 'A' | 'B' | 'C' | 'D' | 'F';
|
|
59
|
+
groundedSpanCount?: number;
|
|
60
|
+
ungroundedSpanCount?: number;
|
|
61
|
+
issues: string[];
|
|
62
|
+
recommendations: string[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* RAG evaluation evidence
|
|
66
|
+
*/
|
|
67
|
+
export interface RAGEvidence {
|
|
68
|
+
groundedSpans: GroundedSpan[];
|
|
69
|
+
ungroundedSpans: UngroundedSpan[];
|
|
70
|
+
citationMap: CitationMap[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Hallucination instance
|
|
74
|
+
*/
|
|
75
|
+
export interface HallucinationInstance {
|
|
76
|
+
type: string;
|
|
77
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
78
|
+
text: string;
|
|
79
|
+
explanation: string;
|
|
80
|
+
confidence: number;
|
|
81
|
+
suggestedFix?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Hallucination detection report
|
|
85
|
+
*/
|
|
86
|
+
export interface HallucinationReport {
|
|
87
|
+
hasHallucinations: boolean;
|
|
88
|
+
hallucinationScore: number;
|
|
89
|
+
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
|
90
|
+
factualClaims: number;
|
|
91
|
+
verifiedClaims: number;
|
|
92
|
+
unverifiedClaims: number;
|
|
93
|
+
summary: string;
|
|
94
|
+
recommendations: string[];
|
|
95
|
+
instances: HallucinationInstance[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Groundedness analysis result
|
|
99
|
+
*/
|
|
100
|
+
export interface GroundednessResult {
|
|
101
|
+
score: number;
|
|
102
|
+
faithfulness: number;
|
|
103
|
+
contextRelevance: number;
|
|
104
|
+
grade: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Batch evaluation result for a single trace
|
|
108
|
+
*/
|
|
109
|
+
export interface BatchEvaluationResult {
|
|
110
|
+
traceId: string;
|
|
111
|
+
success: boolean;
|
|
112
|
+
error?: string;
|
|
113
|
+
rag?: {
|
|
114
|
+
score: number;
|
|
115
|
+
grade: string;
|
|
116
|
+
mainIssue?: string;
|
|
117
|
+
};
|
|
118
|
+
hallucination?: {
|
|
119
|
+
hasIssues: boolean;
|
|
120
|
+
score: number;
|
|
121
|
+
topIssue?: string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Batch evaluation summary
|
|
126
|
+
*/
|
|
127
|
+
export interface BatchEvaluationSummary {
|
|
128
|
+
totalTraces: number;
|
|
129
|
+
successfulEvaluations: number;
|
|
130
|
+
avgRagScore: number;
|
|
131
|
+
hallucinationRate: number;
|
|
132
|
+
gradeDistribution: {
|
|
133
|
+
A: number;
|
|
134
|
+
B: number;
|
|
135
|
+
C: number;
|
|
136
|
+
D: number;
|
|
137
|
+
F: number;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Quality Metrics API client for RAG evaluation and hallucination detection
|
|
142
|
+
*/
|
|
143
|
+
export declare const qualityMetrics: {
|
|
144
|
+
/**
|
|
145
|
+
* Get RAG quality scores for a specific trace
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const scores = await qualityMetrics.getRagScores('trace_abc123');
|
|
150
|
+
* console.log(`Groundedness: ${scores.evaluation.groundedness}`);
|
|
151
|
+
* console.log(`Grade: ${scores.evaluation.grade}`);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
getRagScores(traceId: string): Promise<{
|
|
155
|
+
traceId: string;
|
|
156
|
+
evaluation: RAGEvaluation;
|
|
157
|
+
evidence: RAGEvidence;
|
|
158
|
+
}>;
|
|
159
|
+
/**
|
|
160
|
+
* Get hallucination detection report for a trace
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const report = await qualityMetrics.getHallucinationReport('trace_abc123');
|
|
165
|
+
* if (report.report.hasHallucinations) {
|
|
166
|
+
* console.log(`Risk level: ${report.report.riskLevel}`);
|
|
167
|
+
* for (const instance of report.report.instances) {
|
|
168
|
+
* console.log(`- ${instance.type}: ${instance.text}`);
|
|
169
|
+
* }
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
getHallucinationReport(traceId: string): Promise<{
|
|
174
|
+
traceId: string;
|
|
175
|
+
report: HallucinationReport;
|
|
176
|
+
}>;
|
|
177
|
+
/**
|
|
178
|
+
* Evaluate RAG quality for provided content (ad-hoc evaluation)
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* const result = await qualityMetrics.evaluateRag({
|
|
183
|
+
* query: 'What is the refund policy?',
|
|
184
|
+
* response: 'You can get a refund within 30 days.',
|
|
185
|
+
* retrievedContexts: [
|
|
186
|
+
* { content: 'Our refund policy allows returns within 30 days of purchase.' },
|
|
187
|
+
* ],
|
|
188
|
+
* });
|
|
189
|
+
* console.log(`Groundedness: ${result.evaluation.groundedness}`);
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
evaluateRag(input: {
|
|
193
|
+
query: string;
|
|
194
|
+
response: string;
|
|
195
|
+
retrievedContexts: RetrievedContext[];
|
|
196
|
+
groundTruthContexts?: GroundTruthContext[];
|
|
197
|
+
citations?: string[];
|
|
198
|
+
}): Promise<{
|
|
199
|
+
evaluation: RAGEvaluation;
|
|
200
|
+
evidence: RAGEvidence;
|
|
201
|
+
}>;
|
|
202
|
+
/**
|
|
203
|
+
* Detect hallucinations in provided content (ad-hoc detection)
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* const result = await qualityMetrics.detectHallucinations({
|
|
208
|
+
* response: 'The product costs $99 and comes with a 2-year warranty.',
|
|
209
|
+
* contexts: [
|
|
210
|
+
* { content: 'The product costs $99 with a 1-year warranty.' },
|
|
211
|
+
* ],
|
|
212
|
+
* });
|
|
213
|
+
* if (result.report.hasHallucinations) {
|
|
214
|
+
* console.log('Detected hallucinations:', result.report.instances);
|
|
215
|
+
* }
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
detectHallucinations(input: {
|
|
219
|
+
response: string;
|
|
220
|
+
contexts: Array<{
|
|
221
|
+
content: string;
|
|
222
|
+
metadata?: Record<string, unknown>;
|
|
223
|
+
}>;
|
|
224
|
+
query?: string;
|
|
225
|
+
previousResponses?: string[];
|
|
226
|
+
}): Promise<{
|
|
227
|
+
report: HallucinationReport;
|
|
228
|
+
}>;
|
|
229
|
+
/**
|
|
230
|
+
* Get groundedness analysis for a trace
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* const result = await qualityMetrics.getGroundedness('trace_abc123');
|
|
235
|
+
* console.log(`Groundedness score: ${result.groundedness.score}`);
|
|
236
|
+
* console.log(`Grounded spans: ${result.summary.groundedSpans}`);
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
getGroundedness(traceId: string): Promise<{
|
|
240
|
+
traceId: string;
|
|
241
|
+
groundedness: GroundednessResult;
|
|
242
|
+
spans: {
|
|
243
|
+
grounded: Array<{
|
|
244
|
+
text: string;
|
|
245
|
+
confidence: number;
|
|
246
|
+
sourceIndex: number;
|
|
247
|
+
}>;
|
|
248
|
+
ungrounded: Array<{
|
|
249
|
+
text: string;
|
|
250
|
+
confidence: number;
|
|
251
|
+
}>;
|
|
252
|
+
};
|
|
253
|
+
summary: {
|
|
254
|
+
totalSpans: number;
|
|
255
|
+
groundedSpans: number;
|
|
256
|
+
ungroundedSpans: number;
|
|
257
|
+
groundednessRatio: number;
|
|
258
|
+
};
|
|
259
|
+
}>;
|
|
260
|
+
/**
|
|
261
|
+
* Evaluate multiple traces for quality metrics in batch
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```typescript
|
|
265
|
+
* const result = await qualityMetrics.evaluateBatch({
|
|
266
|
+
* traceIds: ['trace_1', 'trace_2', 'trace_3'],
|
|
267
|
+
* });
|
|
268
|
+
* console.log(`Average RAG score: ${result.summary.avgRagScore}`);
|
|
269
|
+
* console.log(`Hallucination rate: ${result.summary.hallucinationRate}%`);
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
evaluateBatch(options: {
|
|
273
|
+
traceIds: string[];
|
|
274
|
+
includeDetails?: boolean;
|
|
275
|
+
}): Promise<{
|
|
276
|
+
summary: BatchEvaluationSummary;
|
|
277
|
+
results: BatchEvaluationResult[];
|
|
278
|
+
}>;
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Check if a RAG evaluation passes quality thresholds
|
|
282
|
+
*/
|
|
283
|
+
export declare function passesQualityThreshold(evaluation: RAGEvaluation, thresholds?: {
|
|
284
|
+
minGroundedness?: number;
|
|
285
|
+
minOverallScore?: number;
|
|
286
|
+
minGrade?: 'A' | 'B' | 'C' | 'D';
|
|
287
|
+
}): boolean;
|
|
288
|
+
/**
|
|
289
|
+
* Check if hallucination risk is acceptable
|
|
290
|
+
*/
|
|
291
|
+
export declare function isHallucinationRiskAcceptable(report: HallucinationReport, maxRiskLevel?: 'low' | 'medium' | 'high'): boolean;
|
|
292
|
+
/**
|
|
293
|
+
* Get quality recommendations based on evaluation
|
|
294
|
+
*/
|
|
295
|
+
export declare function getQualityRecommendations(ragEval: RAGEvaluation, hallucinationReport?: HallucinationReport): string[];
|
|
296
|
+
/**
|
|
297
|
+
* Format quality score for display
|
|
298
|
+
*/
|
|
299
|
+
export declare function formatQualityScore(score: number): string;
|
|
300
|
+
/**
|
|
301
|
+
* Get color indicator for grade
|
|
302
|
+
*/
|
|
303
|
+
export declare function getGradeColor(grade: 'A' | 'B' | 'C' | 'D' | 'F'): 'green' | 'blue' | 'yellow' | 'orange' | 'red';
|