@thinkhive/sdk 3.1.0 → 3.3.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.
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ /**
3
+ * ThinkHive SDK v3.0 - Conversation Evaluation API
4
+ *
5
+ * API for multi-turn conversation evaluation
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.conversationEval = void 0;
9
+ exports.aggregateWorst = aggregateWorst;
10
+ exports.aggregateAverage = aggregateAverage;
11
+ exports.aggregateWeighted = aggregateWeighted;
12
+ exports.aggregateFinalTurn = aggregateFinalTurn;
13
+ exports.aggregateMajority = aggregateMajority;
14
+ exports.getAggregator = getAggregator;
15
+ exports.getProblematicTurns = getProblematicTurns;
16
+ exports.analyzeConversationTrend = analyzeConversationTrend;
17
+ const client_1 = require("../core/client");
18
+ // ============================================================================
19
+ // CONVERSATION EVAL API CLIENT
20
+ // ============================================================================
21
+ /**
22
+ * Conversation Evaluation API client for multi-turn evaluation
23
+ */
24
+ exports.conversationEval = {
25
+ /**
26
+ * Get traces for a conversation session
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const traces = await conversationEval.getSessionTraces('session_123');
31
+ * console.log(`Conversation has ${traces.length} turns`);
32
+ * ```
33
+ */
34
+ async getSessionTraces(sessionId) {
35
+ return (0, client_1.apiRequestWithData)(`/conversation-eval/traces?sessionId=${sessionId}`, { apiVersion: 'v1' });
36
+ },
37
+ /**
38
+ * Run conversation-level evaluation
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const result = await conversationEval.evaluate({
43
+ * sessionId: 'session_123',
44
+ * criterionId: 'criterion_456',
45
+ * options: {
46
+ * aggregateMethod: 'average',
47
+ * minTurns: 2,
48
+ * },
49
+ * });
50
+ * console.log(`Conversation score: ${result.aggregateScore}`);
51
+ * ```
52
+ */
53
+ async evaluate(options) {
54
+ return (0, client_1.apiRequestWithData)('/conversation-eval/evaluate', {
55
+ method: 'POST',
56
+ body: options,
57
+ apiVersion: 'v1',
58
+ });
59
+ },
60
+ /**
61
+ * Get available aggregation methods with descriptions
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const methods = await conversationEval.getAggregationMethods();
66
+ * for (const method of methods) {
67
+ * console.log(`${method.name}: ${method.description}`);
68
+ * }
69
+ * ```
70
+ */
71
+ async getAggregationMethods() {
72
+ return (0, client_1.apiRequestWithData)('/conversation-eval/aggregation-methods', { apiVersion: 'v1' });
73
+ },
74
+ };
75
+ // ============================================================================
76
+ // HELPER FUNCTIONS
77
+ // ============================================================================
78
+ /**
79
+ * Calculate worst-turn aggregation
80
+ *
81
+ * @param turnResults - Array of turn evaluation results
82
+ * @returns Aggregated result using worst turn logic
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const result = aggregateWorst(turnResults);
87
+ * // Fails if any turn fails
88
+ * ```
89
+ */
90
+ function aggregateWorst(turnResults) {
91
+ if (turnResults.length === 0)
92
+ return { passed: false, score: 0 };
93
+ const worstScore = Math.min(...turnResults.map(t => t.score));
94
+ const passed = turnResults.every(t => t.passed);
95
+ return { passed, score: worstScore };
96
+ }
97
+ /**
98
+ * Calculate average aggregation
99
+ *
100
+ * @param turnResults - Array of turn evaluation results
101
+ * @returns Aggregated result using average logic
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const result = aggregateAverage(turnResults);
106
+ * ```
107
+ */
108
+ function aggregateAverage(turnResults) {
109
+ if (turnResults.length === 0)
110
+ return { passed: false, score: 0 };
111
+ const avgScore = turnResults.reduce((sum, t) => sum + t.score, 0) / turnResults.length;
112
+ const passedCount = turnResults.filter(t => t.passed).length;
113
+ const passed = passedCount > turnResults.length / 2;
114
+ return { passed, score: avgScore };
115
+ }
116
+ /**
117
+ * Calculate weighted average aggregation (later turns weighted more)
118
+ *
119
+ * @param turnResults - Array of turn evaluation results
120
+ * @returns Aggregated result using weighted average logic
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const result = aggregateWeighted(turnResults);
125
+ * // Later turns have higher weight
126
+ * ```
127
+ */
128
+ function aggregateWeighted(turnResults) {
129
+ if (turnResults.length === 0)
130
+ return { passed: false, score: 0 };
131
+ // Linear weights: 1, 2, 3, ...
132
+ let weightedSum = 0;
133
+ let weightTotal = 0;
134
+ let weightedPassSum = 0;
135
+ turnResults.forEach((turn, index) => {
136
+ const weight = index + 1;
137
+ weightedSum += turn.score * weight;
138
+ weightedPassSum += (turn.passed ? 1 : 0) * weight;
139
+ weightTotal += weight;
140
+ });
141
+ const avgScore = weightedSum / weightTotal;
142
+ const passed = (weightedPassSum / weightTotal) > 0.5;
143
+ return { passed, score: avgScore };
144
+ }
145
+ /**
146
+ * Calculate final-turn aggregation
147
+ *
148
+ * @param turnResults - Array of turn evaluation results
149
+ * @returns Aggregated result using only the final turn
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * const result = aggregateFinalTurn(turnResults);
154
+ * // Only final turn matters
155
+ * ```
156
+ */
157
+ function aggregateFinalTurn(turnResults) {
158
+ if (turnResults.length === 0)
159
+ return { passed: false, score: 0 };
160
+ const finalTurn = turnResults[turnResults.length - 1];
161
+ return { passed: finalTurn.passed, score: finalTurn.score };
162
+ }
163
+ /**
164
+ * Calculate majority vote aggregation
165
+ *
166
+ * @param turnResults - Array of turn evaluation results
167
+ * @returns Aggregated result using majority vote logic
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const result = aggregateMajority(turnResults);
172
+ * // Passes if majority of turns pass
173
+ * ```
174
+ */
175
+ function aggregateMajority(turnResults) {
176
+ if (turnResults.length === 0)
177
+ return { passed: false, score: 0 };
178
+ const passedCount = turnResults.filter(t => t.passed).length;
179
+ const passed = passedCount > turnResults.length / 2;
180
+ const avgScore = turnResults.reduce((sum, t) => sum + t.score, 0) / turnResults.length;
181
+ return { passed, score: avgScore };
182
+ }
183
+ /**
184
+ * Get appropriate aggregation function for a method
185
+ *
186
+ * @param method - Aggregation method name
187
+ * @returns Aggregation function
188
+ */
189
+ function getAggregator(method) {
190
+ switch (method) {
191
+ case 'worst': return aggregateWorst;
192
+ case 'average': return aggregateAverage;
193
+ case 'weighted': return aggregateWeighted;
194
+ case 'final_turn': return aggregateFinalTurn;
195
+ case 'majority': return aggregateMajority;
196
+ default: return aggregateAverage;
197
+ }
198
+ }
199
+ /**
200
+ * Find problematic turns in a conversation
201
+ *
202
+ * @param result - Conversation evaluation result
203
+ * @param scoreThreshold - Minimum acceptable score (default 70)
204
+ * @returns Array of problematic turn results
205
+ */
206
+ function getProblematicTurns(result, scoreThreshold = 70) {
207
+ return result.turnResults.filter(t => !t.passed || t.score < scoreThreshold);
208
+ }
209
+ /**
210
+ * Calculate conversation quality trend
211
+ *
212
+ * @param result - Conversation evaluation result
213
+ * @returns Trend analysis
214
+ */
215
+ function analyzeConversationTrend(result) {
216
+ const turns = result.turnResults;
217
+ if (turns.length < 2) {
218
+ return { direction: 'stable', firstHalfAvg: 0, secondHalfAvg: 0 };
219
+ }
220
+ const midpoint = Math.floor(turns.length / 2);
221
+ const firstHalf = turns.slice(0, midpoint);
222
+ const secondHalf = turns.slice(midpoint);
223
+ const firstHalfAvg = firstHalf.reduce((sum, t) => sum + t.score, 0) / firstHalf.length;
224
+ const secondHalfAvg = secondHalf.reduce((sum, t) => sum + t.score, 0) / secondHalf.length;
225
+ const diff = secondHalfAvg - firstHalfAvg;
226
+ let direction;
227
+ if (diff > 5)
228
+ direction = 'improving';
229
+ else if (diff < -5)
230
+ direction = 'declining';
231
+ else
232
+ direction = 'stable';
233
+ return { direction, firstHalfAvg, secondHalfAvg };
234
+ }
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVyc2F0aW9uLWV2YWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2NvbnZlcnNhdGlvbi1ldmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7OztHQUlHOzs7QUE0SUgsd0NBT0M7QUFhRCw0Q0FRQztBQWNELDhDQW1CQztBQWNELGdEQUtDO0FBY0QsOENBUUM7QUFRRCxzQ0FXQztBQVNELGtEQUtDO0FBUUQsNERBeUJDO0FBbFRELDJDQUFvRDtBQXVEcEQsK0VBQStFO0FBQy9FLCtCQUErQjtBQUMvQiwrRUFBK0U7QUFFL0U7O0dBRUc7QUFDVSxRQUFBLGdCQUFnQixHQUFHO0lBQzlCOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQWlCO1FBQ3RDLE9BQU8sSUFBQSwyQkFBa0IsRUFDdkIsdUNBQXVDLFNBQVMsRUFBRSxFQUNsRCxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FDckIsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQW9DO1FBQ2pELE9BQU8sSUFBQSwyQkFBa0IsRUFBeUIsNkJBQTZCLEVBQUU7WUFDL0UsTUFBTSxFQUFFLE1BQU07WUFDZCxJQUFJLEVBQUUsT0FBTztZQUNiLFVBQVUsRUFBRSxJQUFJO1NBQ2pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQjtRQUN6QixPQUFPLElBQUEsMkJBQWtCLEVBQ3ZCLHdDQUF3QyxFQUN4QyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FDckIsQ0FBQztJQUNKLENBQUM7Q0FDRixDQUFDO0FBRUYsK0VBQStFO0FBQy9FLG1CQUFtQjtBQUNuQiwrRUFBK0U7QUFFL0U7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixjQUFjLENBQUMsV0FBNkI7SUFDMUQsSUFBSSxXQUFXLENB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QU0sSUFBSSxHQUFHLGFBQWEsR0FBRyxZQUFZLENBQUM7SUFDMUMsSUFBSSxTQUErQyxDQUFDO0lBRXBELElBQUksSUFBSSxHQUFHLENBQUM7UUFBRSxTQUFTLEdBQUcsV0FBVyxDQUFDO1NBQ2pDLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQztRQUFFLFNBQVMsR0FBRyxXQUFXLENBQUM7O1FBQ3ZDLFNBQVMsR0FBRyxRQUFRLENBQUM7SUFFMUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLENBQUM7QUFDcEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhpbmtIaXZlIFNESyB2My4wIC0gQ29udmVyc2F0aW9uIEV2YWx1YXRpb24gQVBJXG4gKlxuICogQVBJIGZvciBtdWx0aS10dXJuIGNvbnZlcnNhdGlvbiBldmFsdWF0aW9uXG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgdHlwZSBBZ2dyZWdhdGVNZXRob2QgPSAnd29yc3QnIHwgJ2F2ZXJhZ2UnIHwgJ3dlaWdodGVkJyB8ICdmaW5hbF90dXJuJyB8ICdtYWpvcml0eSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvblRyYWNlIHtcbiAgaWQ6IHN0cmluZztcbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIHR1cm5OdW1iZXI6IG51bWJlcjtcbiAgdXNlck1lc3NhZ2U6IHN0cmluZztcbiAgYWdlbnRSZXNwb25zZTogc3RyaW5nO1xuICB0aW1lc3RhbXA6IHN0cmluZztcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUdXJuRXZhbHVhdGlvbiB7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgdHVybk51bWJlcjogbnVtYmVyO1xuICBwYXNzZWQ6IGJvb2xlYW47XG4gIHNjb3JlOiBudW1iZXI7XG4gIHJlYXNvbmluZzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZlcnNhdGlvbkV2YWxSZXN1bHQge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ6IHN0cmluZztcbiAgdHVybkNvdW50OiBudW1iZXI7XG4gIHR1cm5SZXN1bHRzOiBUdXJuRXZhbHVhdGlvbltdO1xuICBhZ2dyZWdhdGVQYXNzZWQ6IGJvb2xlYW47XG4gIGFnZ3JlZ2F0ZVNjb3JlOiBudW1iZXI7XG4gIGFnZ3JlZ2F0ZU1ldGhvZDogQWdncmVnYXRlTWV0aG9kO1xuICByZWFzb25pbmc6IHN0cmluZztcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFdmFsdWF0ZUNvbnZlcnNhdGlvbk9wdGlvbnMge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ6IHN0cmluZztcbiAgb3B0aW9ucz86IHtcbiAgICBhZ2dyZWdhdGVNZXRob2Q/OiBBZ2dyZWdhdGVNZXRob2Q7XG4gICAgbWluVHVybnM/OiBudW1iZXI7XG4gICAgbWF4VHVybnM/OiBudW1iZXI7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWdncmVnYXRpb25NZXRob2RJbmZvIHtcbiAgaWQ6IEFnZ3JlZ2F0ZU1ldGhvZDtcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB1c2VDYXNlOiBzdHJpbmc7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENPTlZFUlNBVElPTiBFVkFMIEFQSSBDTElFTlRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDb252ZXJzYXRpb24gRXZhbHVhdGlvbiBBUEkgY2xpZW50IGZvciBtdWx0aS10dXJuIGV2YWx1YXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnZlcnNhdGlvbkV2YWwgPSB7XG4gIC8qKlxuICAgKiBHZXQgdHJhY2VzIGZvciBhIGNvbnZlcnNhdGlvbiBzZXNzaW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgdHJhY2VzID0gYXdhaXQgY29udmVyc2F0aW9uRXZhbC5nZXRTZXNzaW9uVHJhY2VzKCdzZXNzaW9uXzEyMycpO1xuICAgKiBjb25zb2xlLmxvZyhgQ29udmVyc2F0aW9uIGhhcyAke3RyYWNlcy5sZW5ndGh9IHR1cm5zYCk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0U2Vzc2lvblRyYWNlcyhzZXNzaW9uSWQ6IHN0cmluZyk6IFByb21pc2U8U2Vzc2lvblRyYWNlW10+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPFNlc3Npb25UcmFjZVtdPihcbiAgICAgIGAvY29udmVyc2F0aW9uLWV2YWwvdHJhY2VzP3Nlc3Npb25JZD0ke3Nlc3Npb25JZH1gLFxuICAgICAgeyBhcGlWZXJzaW9uOiAndjEnIH1cbiAgICApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSdW4gY29udmVyc2F0aW9uLWxldmVsIGV2YWx1YXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBjb252ZXJzYXRpb25FdmFsLmV2YWx1YXRlKHtcbiAgICogICBzZXNzaW9uSWQ6ICdzZXNzaW9uXzEyMycsXG4gICAqICAgY3JpdGVyaW9uSWQ6ICdjcml0ZXJpb25fNDU2JyxcbiAgICogICBvcHRpb25zOiB7XG4gICAqICAgICBhZ2dyZWdhdGVNZXRob2Q6ICdhdmVyYWdlJyxcbiAgICogICAgIG1pblR1cm5zOiAyLFxuICAgKiAgIH0sXG4gICAqIH0pO1xuICAgKiBjb25zb2xlLmxvZyhgQ29udmVyc2F0aW9uIHNjb3JlOiAke3Jlc3VsdC5hZ2dyZWdhdGVTY29yZX1gKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBldmFsdWF0ZShvcHRpb25zOiBFdmFsdWF0ZUNvbnZlcnNhdGlvbk9wdGlvbnMpOiBQcm9taXNlPENvbnZlcnNhdGlvbkV2YWxSZXN1bHQ+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPENvbnZlcnNhdGlvbkV2YWxSZXN1bHQ+KCcvY29udmVyc2F0aW9uLWV2YWwvZXZhbHVhdGUnLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICBhcGlWZXJzaW9uOiAndjEnLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgYXZhaWxhYmxlIGFnZ3JlZ2F0aW9uIG1ldGhvZHMgd2l0aCBkZXNjcmlwdGlvbnNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBtZXRob2RzID0gYXdhaXQgY29udmVyc2F0aW9uRXZhbC5nZXRBZ2dyZWdhdGlvbk1ldGhvZHMoKTtcbiAgICogZm9yIChjb25zdCBtZXRob2Qgb2YgbWV0aG9kcykge1xuICAgKiAgIGNvbnNvbGUubG9nKGAke21ldGhvZC5uYW1lfTogJHttZXRob2QuZGVzY3JpcHRpb259YCk7XG4gICAqIH1cbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBnZXRBZ2dyZWdhdGlvbk1ldGhvZHMoKTogUHJvbWlzZTxBZ2dyZWdhdGlvbk1ldGhvZEluZm9bXT4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8QWdncmVnYXRpb25NZXRob2RJbmZvW10+KFxuICAgICAgJy9jb252ZXJzYXRpb24tZXZhbC9hZ2dyZWdhdGlvbi1tZXRob2RzJyxcbiAgICAgIHsgYXBpVmVyc2lvbjogJ3YxJyB9XG4gICAgKTtcbiAgfSxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDYWxjdWxhdGUgd29yc3QtdHVybiBhZ2dyZWdhdGlvblxuICpcbiAqIEBwYXJhbSB0dXJuUmVzdWx0cyAtIEFycmF5IG9mIHR1cm4gZXZhbHVhdGlvbiByZXN1bHRzXG4gKiBAcmV0dXJucyBBZ2dyZWdhdGVkIHJlc3VsdCB1c2luZyB3b3JzdCB0dXJuIGxvZ2ljXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdCA9IGFnZ3JlZ2F0ZVdvcnN0KHR1cm5SZXN1bHRzKTtcbiAqIC8vIEZhaWxzIGlmIGFueSB0dXJuIGZhaWxzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFnZ3JlZ2F0ZVdvcnN0KHR1cm5SZXN1bHRzOiBUdXJuRXZhbHVhdGlvbltdKTogeyBwYXNzZWQ6IGJvb2xlYW47IHNjb3JlOiBudW1iZXIgfSB7XG4gIGlmICh0dXJuUmVzdWx0cy5sZW5ndGggPT09IDApIHJldHVybiB7IHBhc3NlZDogZmFsc2UsIHNjb3JlOiAwIH07XG5cbiAgY29uc3Qgd29yc3RTY29yZSA9IE1hdGgubWluKC4uLnR1cm5SZXN1bHRzLm1hcCh0ID0+IHQuc2NvcmUpKTtcbiAgY29uc3QgcGFzc2VkID0gdHVyblJlc3VsdHMuZXZlcnkodCA9PiB0LnBhc3NlZCk7XG5cbiAgcmV0dXJuIHsgcGFzc2VkLCBzY29yZTogd29yc3RTY29yZSB9O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBhdmVyYWdlIGFnZ3JlZ2F0aW9uXG4gKlxuICogQHBhcmFtIHR1cm5SZXN1bHRzIC0gQXJyYXkgb2YgdHVybiBldmFsdWF0aW9uIHJlc3VsdHNcbiAqIEByZXR1cm5zIEFnZ3JlZ2F0ZWQgcmVzdWx0IHVzaW5nIGF2ZXJhZ2UgbG9naWNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzdWx0ID0gYWdncmVnYXRlQXZlcmFnZSh0dXJuUmVzdWx0cyk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFnZ3JlZ2F0ZUF2ZXJhZ2UodHVyblJlc3VsdHM6IFR1cm5FdmFsdWF0aW9uW10pOiB7IHBhc3NlZDogYm9vbGVhbjsgc2NvcmU6IG51bWJlciB9IHtcbiAgaWYgKHR1cm5SZXN1bHRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgcGFzc2VkOiBmYWxzZSwgc2NvcmU6IDAgfTtcblxuICBjb25zdCBhdmdTY29yZSA9IHR1cm5SZXN1bHRzLnJlZHVjZSgoc3VtLCB0KSA9PiBzdW0gKyB0LnNjb3JlLCAwKSAvIHR1cm5SZXN1bHRzLmxlbmd0aDtcbiAgY29uc3QgcGFzc2VkQ291bnQgPSB0dXJuUmVzdWx0cy5maWx0ZXIodCA9PiB0LnBhc3NlZCkubGVuZ3RoO1xuICBjb25zdCBwYXNzZWQgPSBwYXNzZWRDb3VudCA+IHR1cm5SZXN1bHRzLmxlbmd0aCAvIDI7XG5cbiAgcmV0dXJuIHsgcGFzc2VkLCBzY29yZTogYXZnU2NvcmUgfTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgd2VpZ2h0ZWQgYXZlcmFnZSBhZ2dyZWdhdGlvbiAobGF0ZXIgdHVybnMgd2VpZ2h0ZWQgbW9yZSlcbiAqXG4gKiBAcGFyYW0gdHVyblJlc3VsdHMgLSBBcnJheSBvZiB0dXJuIGV2YWx1YXRpb24gcmVzdWx0c1xuICogQHJldHVybnMgQWdncmVnYXRlZCByZXN1bHQgdXNpbmcgd2VpZ2h0ZWQgYXZlcmFnZSBsb2dpY1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXN1bHQgPSBhZ2dyZWdhdGVXZWlnaHRlZCh0dXJuUmVzdWx0cyk7XG4gKiAvLyBMYXRlciB0dXJucyBoYXZlIGhpZ2hlciB3ZWlnaHRcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYWdncmVnYXRlV2VpZ2h0ZWQodHVyblJlc3VsdHM6IFR1cm5FdmFsdWF0aW9uW10pOiB7IHBhc3NlZDogYm9vbGVhbjsgc2NvcmU6IG51bWJlciB9IHtcbiAgaWYgKHR1cm5SZXN1bHRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgcGFzc2VkOiBmYWxzZSwgc2NvcmU6IDAgfTtcblxuICAvLyBMaW5lYXIgd2VpZ2h0czogMSwgMiwgMywgLi4uXG4gIGxldCB3ZWlnaHRlZFN1bSA9IDA7XG4gIGxldCB3ZWlnaHRUb3RhbCA9IDA7XG4gIGxldCB3ZWlnaHRlZFBhc3NTdW0gPSAwO1xuXG4gIHR1cm5SZXN1bHRzLmZvckVhY2goKHR1cm4sIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgd2VpZ2h0ID0gaW5kZXggKyAxO1xuICAgIHdlaWdodGVkU3VtICs9IHR1cm4uc2NvcmUgKiB3ZWlnaHQ7XG4gICAgd2VpZ2h0ZWRQYXNzU3VtICs9ICh0dXJuLnBhc3NlZCA/IDEgOiAwKSAqIHdlaWdodDtcbiAgICB3ZWlnaHRUb3RhbCArPSB3ZWlnaHQ7XG4gIH0pO1xuXG4gIGNvbnN0IGF2Z1Njb3JlID0gd2VpZ2h0ZWRTdW0gLyB3ZWlnaHRUb3RhbDtcbiAgY29uc3QgcGFzc2VkID0gKHdlaWdodGVkUGFzc1N1bSAvIHdlaWdodFRvdGFsKSA+IDAuNTtcblxuICByZXR1cm4geyBwYXNzZWQsIHNjb3JlOiBhdmdTY29yZSB9O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBmaW5hbC10dXJuIGFnZ3JlZ2F0aW9uXG4gKlxuICogQHBhcmFtIHR1cm5SZXN1bHRzIC0gQXJyYXkgb2YgdHVybiBldmFsdWF0aW9uIHJlc3VsdHNcbiAqIEByZXR1cm5zIEFnZ3JlZ2F0ZWQgcmVzdWx0IHVzaW5nIG9ubHkgdGhlIGZpbmFsIHR1cm5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzdWx0ID0gYWdncmVnYXRlRmluYWxUdXJuKHR1cm5SZXN1bHRzKTtcbiAqIC8vIE9ubHkgZmluYWwgdHVybiBtYXR0ZXJzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFnZ3JlZ2F0ZUZpbmFsVHVybih0dXJuUmVzdWx0czogVHVybkV2YWx1YXRpb25bXSk6IHsgcGFzc2VkOiBib29sZWFuOyBzY29yZTogbnVtYmVyIH0ge1xuICBpZiAodHVyblJlc3VsdHMubGVuZ3RoID09PSAwKSByZXR1cm4geyBwYXNzZWQ6IGZhbHNlLCBzY29yZTogMCB9O1xuXG4gIGNvbnN0IGZpbmFsVHVybiA9IHR1cm5SZXN1bHRzW3R1cm5SZXN1bHRzLmxlbmd0aCAtIDFdO1xuICByZXR1cm4geyBwYXNzZWQ6IGZpbmFsVHVybi5wYXNzZWQsIHNjb3JlOiBmaW5hbFR1cm4uc2NvcmUgfTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgbWFqb3JpdHkgdm90ZSBhZ2dyZWdhdGlvblxuICpcbiAqIEBwYXJhbSB0dXJuUmVzdWx0cyAtIEFycmF5IG9mIHR1cm4gZXZhbHVhdGlvbiByZXN1bHRzXG4gKiBAcmV0dXJucyBBZ2dyZWdhdGVkIHJlc3VsdCB1c2luZyBtYWpvcml0eSB2b3RlIGxvZ2ljXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdCA9IGFnZ3JlZ2F0ZU1ham9yaXR5KHR1cm5SZXN1bHRzKTtcbiAqIC8vIFBhc3NlcyBpZiBtYWpvcml0eSBvZiB0dXJucyBwYXNzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFnZ3JlZ2F0ZU1ham9yaXR5KHR1cm5SZXN1bHRzOiBUdXJuRXZhbHVhdGlvbltdKTogeyBwYXNzZWQ6IGJvb2xlYW47IHNjb3JlOiBudW1iZXIgfSB7XG4gIGlmICh0dXJuUmVzdWx0cy5sZW5ndGggPT09IDApIHJldHVybiB7IHBhc3NlZDogZmFsc2UsIHNjb3JlOiAwIH07XG5cbiAgY29uc3QgcGFzc2VkQ291bnQgPSB0dXJuUmVzdWx0cy5maWx0ZXIodCA9PiB0LnBhc3NlZCkubGVuZ3RoO1xuICBjb25zdCBwYXNzZWQgPSBwYXNzZWRDb3VudCA+IHR1cm5SZXN1bHRzLmxlbmd0aCAvIDI7XG4gIGNvbnN0IGF2Z1Njb3JlID0gdHVyblJlc3VsdHMucmVkdWNlKChzdW0sIHQpID0+IHN1bSArIHQuc2NvcmUsIDApIC8gdHVyblJlc3VsdHMubGVuZ3RoO1xuXG4gIHJldHVybiB7IHBhc3NlZCwgc2NvcmU6IGF2Z1Njb3JlIH07XG59XG5cbi8qKlxuICogR2V0IGFwcHJvcHJpYXRlIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uIGZvciBhIG1ldGhvZFxuICpcbiAqIEBwYXJhbSBtZXRob2QgLSBBZ2dyZWdhdGlvbiBtZXRob2QgbmFtZVxuICogQHJldHVybnMgQWdncmVnYXRpb24gZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFnZ3JlZ2F0b3IoXG4gIG1ldGhvZDogQWdncmVnYXRlTWV0aG9kXG4pOiAodHVyblJlc3VsdHM6IFR1cm5FdmFsdWF0aW9uW10pID0+IHsgcGFzc2VkOiBib29sZWFuOyBzY29yZTogbnVtYmVyIH0ge1xuICBzd2l0Y2ggKG1ldGhvZCkge1xuICAgIGNhc2UgJ3dvcnN0JzogcmV0dXJuIGFnZ3JlZ2F0ZVdvcnN0O1xuICAgIGNhc2UgJ2F2ZXJhZ2UnOiByZXR1cm4gYWdncmVnYXRlQXZlcmFnZTtcbiAgICBjYXNlICd3ZWlnaHRlZCc6IHJldHVybiBhZ2dyZWdhdGVXZWlnaHRlZDtcbiAgICBjYXNlICdmaW5hbF90dXJuJzogcmV0dXJuIGFnZ3JlZ2F0ZUZpbmFsVHVybjtcbiAgICBjYXNlICdtYWpvcml0eSc6IHJldHVybiBhZ2dyZWdhdGVNYWpvcml0eTtcbiAgICBkZWZhdWx0OiByZXR1cm4gYWdncmVnYXRlQXZlcmFnZTtcbiAgfVxufVxuXG4vKipcbiAqIEZpbmQgcHJvYmxlbWF0aWMgdHVybnMgaW4gYSBjb252ZXJzYXRpb25cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gQ29udmVyc2F0aW9uIGV2YWx1YXRpb24gcmVzdWx0XG4gKiBAcGFyYW0gc2NvcmVUaHJlc2hvbGQgLSBNaW5pbXVtIGFjY2VwdGFibGUgc2NvcmUgKGRlZmF1bHQgNzApXG4gKiBAcmV0dXJucyBBcnJheSBvZiBwcm9ibGVtYXRpYyB0dXJuIHJlc3VsdHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFByb2JsZW1hdGljVHVybnMoXG4gIHJlc3VsdDogQ29udmVyc2F0aW9uRXZhbFJlc3VsdCxcbiAgc2NvcmVUaHJlc2hvbGQgPSA3MFxuKTogVHVybkV2YWx1YXRpb25bXSB7XG4gIHJldHVybiByZXN1bHQudHVyblJlc3VsdHMuZmlsdGVyKHQgPT4gIXQucGFzc2VkIHx8IHQuc2NvcmUgPCBzY29yZVRocmVzaG9sZCk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIGNvbnZlcnNhdGlvbiBxdWFsaXR5IHRyZW5kXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIENvbnZlcnNhdGlvbiBldmFsdWF0aW9uIHJlc3VsdFxuICogQHJldHVybnMgVHJlbmQgYW5hbHlzaXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuYWx5emVDb252ZXJzYXRpb25UcmVuZChyZXN1bHQ6IENvbnZlcnNhdGlvbkV2YWxSZXN1bHQpOiB7XG4gIGRpcmVjdGlvbjogJ2ltcHJvdmluZycgfCAnZGVjbGluaW5nJyB8ICdzdGFibGUnO1xuICBmaXJzdEhhbGZBdmc6IG51bWJlcjtcbiAgc2Vjb25kSGFsZkF2ZzogbnVtYmVyO1xufSB7XG4gIGNvbnN0IHR1cm5zID0gcmVzdWx0LnR1cm5SZXN1bHRzO1xuICBpZiAodHVybnMubGVuZ3RoIDwgMikge1xuICAgIHJldHVybiB7IGRpcmVjdGlvbjogJ3N0YWJsZScsIGZpcnN0SGFsZkF2ZzogMCwgc2Vjb25kSGFsZkF2ZzogMCB9O1xuICB9XG5cbiAgY29uc3QgbWlkcG9pbnQgPSBNYXRoLmZsb29yKHR1cm5zLmxlbmd0aCAvIDIpO1xuICBjb25zdCBmaXJzdEhhbGYgPSB0dXJucy5zbGljZSgwLCBtaWRwb2ludCk7XG4gIGNvbnN0IHNlY29uZEhhbGYgPSB0dXJucy5zbGljZShtaWRwb2ludCk7XG5cbiAgY29uc3QgZmlyc3RIYWxmQXZnID0gZmlyc3RIYWxmLnJlZHVjZSgoc3VtLCB0KSA9PiBzdW0gKyB0LnNjb3JlLCAwKSAvIGZpcnN0SGFsZi5sZW5ndGg7XG4gIGNvbnN0IHNlY29uZEhhbGZBdmcgPSBzZWNvbmRIYWxmLnJlZHVjZSgoc3VtLCB0KSA9PiBzdW0gKyB0LnNjb3JlLCAwKSAvIHNlY29uZEhhbGYubGVuZ3RoO1xuXG4gIGNvbnN0IGRpZmYgPSBzZWNvbmRIYWxmQXZnIC0gZmlyc3RIYWxmQXZnO1xuICBsZXQgZGlyZWN0aW9uOiAnaW1wcm92aW5nJyB8ICdkZWNsaW5pbmcnIHwgJ3N0YWJsZSc7XG5cbiAgaWYgKGRpZmYgPiA1KSBkaXJlY3Rpb24gPSAnaW1wcm92aW5nJztcbiAgZWxzZSBpZiAoZGlmZiA8IC01KSBkaXJlY3Rpb24gPSAnZGVjbGluaW5nJztcbiAgZWxzZSBkaXJlY3Rpb24gPSAnc3RhYmxlJztcblxuICByZXR1cm4geyBkaXJlY3Rpb24sIGZpcnN0SGFsZkF2Zywgc2Vjb25kSGFsZkF2ZyB9O1xufVxuIl19
@@ -0,0 +1,205 @@
1
+ /**
2
+ * ThinkHive SDK v3.0 - Deterministic Graders API
3
+ *
4
+ * API for running deterministic (code-based) evaluations
5
+ */
6
+ export type RuleType = 'regex' | 'contains' | 'not_contains' | 'json_valid' | 'json_schema' | 'length' | 'pii_check' | 'sentiment' | 'latency' | 'token_count';
7
+ export interface DeterministicEvalResult {
8
+ passed: boolean;
9
+ score: number;
10
+ reasoning: string;
11
+ ruleResults?: RuleResult[];
12
+ metadata?: Record<string, unknown>;
13
+ }
14
+ export interface RuleResult {
15
+ ruleId: string;
16
+ ruleName: string;
17
+ ruleType: RuleType;
18
+ passed: boolean;
19
+ score: number;
20
+ details?: string;
21
+ }
22
+ export interface EvaluateOptions {
23
+ traceId: string;
24
+ criterionId: string;
25
+ }
26
+ export interface BulkEvaluateOptions {
27
+ evaluations: Array<{
28
+ traceId: string;
29
+ criterionId: string;
30
+ }>;
31
+ }
32
+ export interface BulkEvaluateResult {
33
+ results: Array<{
34
+ traceId: string;
35
+ criterionId: string;
36
+ passed: boolean;
37
+ score: number;
38
+ error?: string;
39
+ }>;
40
+ summary: {
41
+ total: number;
42
+ passed: number;
43
+ failed: number;
44
+ passRate: number;
45
+ };
46
+ }
47
+ export interface RuleTypeInfo {
48
+ id: RuleType;
49
+ name: string;
50
+ description: string;
51
+ configFields: string[];
52
+ }
53
+ export interface RuleTemplate {
54
+ id: string;
55
+ name: string;
56
+ description: string;
57
+ ruleType: RuleType;
58
+ config: Record<string, unknown>;
59
+ }
60
+ /**
61
+ * Deterministic Graders API client for code-based evaluations
62
+ */
63
+ export declare const deterministicGraders: {
64
+ /**
65
+ * Run deterministic evaluation on a single trace
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const result = await deterministicGraders.evaluate({
70
+ * traceId: 'trace_123',
71
+ * criterionId: 'criterion_456',
72
+ * });
73
+ * console.log(`Passed: ${result.passed}, Score: ${result.score}`);
74
+ * ```
75
+ */
76
+ evaluate(options: EvaluateOptions): Promise<DeterministicEvalResult>;
77
+ /**
78
+ * Run deterministic evaluations on multiple traces
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const { results, summary } = await deterministicGraders.bulkEvaluate({
83
+ * evaluations: [
84
+ * { traceId: 'trace_1', criterionId: 'criterion_456' },
85
+ * { traceId: 'trace_2', criterionId: 'criterion_456' },
86
+ * { traceId: 'trace_3', criterionId: 'criterion_456' },
87
+ * ],
88
+ * });
89
+ * console.log(`Pass rate: ${summary.passRate * 100}%`);
90
+ * ```
91
+ */
92
+ bulkEvaluate(options: BulkEvaluateOptions): Promise<BulkEvaluateResult>;
93
+ /**
94
+ * Get available rule types with descriptions
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const ruleTypes = await deterministicGraders.getRuleTypes();
99
+ * for (const type of ruleTypes) {
100
+ * console.log(`${type.name}: ${type.description}`);
101
+ * }
102
+ * ```
103
+ */
104
+ getRuleTypes(): Promise<RuleTypeInfo[]>;
105
+ /**
106
+ * Get rule templates
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const templates = await deterministicGraders.getTemplates();
111
+ * const noPiiTemplate = templates.find(t => t.id === 'no_pii');
112
+ * ```
113
+ */
114
+ getTemplates(): Promise<RuleTemplate[]>;
115
+ };
116
+ /**
117
+ * Create a regex rule configuration
118
+ *
119
+ * @param pattern - Regular expression pattern
120
+ * @param flags - Regex flags (default: 'gi')
121
+ * @returns Rule configuration object
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * const config = createRegexRule('\\b(error|fail)\\b', 'gi');
126
+ * ```
127
+ */
128
+ export declare function createRegexRule(pattern: string, flags?: string): {
129
+ pattern: string;
130
+ flags: string;
131
+ };
132
+ /**
133
+ * Create a contains rule configuration
134
+ *
135
+ * @param values - Strings to check for
136
+ * @param caseSensitive - Whether comparison is case-sensitive
137
+ * @returns Rule configuration object
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const config = createContainsRule(['hello', 'hi', 'hey'], false);
142
+ * ```
143
+ */
144
+ export declare function createContainsRule(values: string[], caseSensitive?: boolean): {
145
+ values: string[];
146
+ caseSensitive: boolean;
147
+ };
148
+ /**
149
+ * Create a length rule configuration
150
+ *
151
+ * @param min - Minimum length (optional)
152
+ * @param max - Maximum length (optional)
153
+ * @returns Rule configuration object
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * const config = createLengthRule(50, 1000);
158
+ * ```
159
+ */
160
+ export declare function createLengthRule(min?: number, max?: number): {
161
+ min?: number;
162
+ max?: number;
163
+ };
164
+ /**
165
+ * Create a JSON schema rule configuration
166
+ *
167
+ * @param schema - JSON Schema object
168
+ * @returns Rule configuration object
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const config = createJsonSchemaRule({
173
+ * type: 'object',
174
+ * required: ['name', 'email'],
175
+ * properties: {
176
+ * name: { type: 'string' },
177
+ * email: { type: 'string', format: 'email' },
178
+ * },
179
+ * });
180
+ * ```
181
+ */
182
+ export declare function createJsonSchemaRule(schema: Record<string, unknown>): {
183
+ schema: Record<string, unknown>;
184
+ };
185
+ /**
186
+ * Check if all rule results passed
187
+ *
188
+ * @param results - Array of rule results
189
+ * @returns Whether all rules passed
190
+ */
191
+ export declare function allRulesPassed(results: RuleResult[]): boolean;
192
+ /**
193
+ * Get failed rules from results
194
+ *
195
+ * @param results - Array of rule results
196
+ * @returns Array of failed rule results
197
+ */
198
+ export declare function getFailedRules(results: RuleResult[]): RuleResult[];
199
+ /**
200
+ * Calculate average score from rule results
201
+ *
202
+ * @param results - Array of rule results
203
+ * @returns Average score (0-100)
204
+ */
205
+ export declare function calculateAverageScore(results: RuleResult[]): number;
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * ThinkHive SDK v3.0 - Deterministic Graders API
4
+ *
5
+ * API for running deterministic (code-based) evaluations
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.deterministicGraders = void 0;
9
+ exports.createRegexRule = createRegexRule;
10
+ exports.createContainsRule = createContainsRule;
11
+ exports.createLengthRule = createLengthRule;
12
+ exports.createJsonSchemaRule = createJsonSchemaRule;
13
+ exports.allRulesPassed = allRulesPassed;
14
+ exports.getFailedRules = getFailedRules;
15
+ exports.calculateAverageScore = calculateAverageScore;
16
+ const client_1 = require("../core/client");
17
+ // ============================================================================
18
+ // DETERMINISTIC GRADERS API CLIENT
19
+ // ============================================================================
20
+ /**
21
+ * Deterministic Graders API client for code-based evaluations
22
+ */
23
+ exports.deterministicGraders = {
24
+ /**
25
+ * Run deterministic evaluation on a single trace
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const result = await deterministicGraders.evaluate({
30
+ * traceId: 'trace_123',
31
+ * criterionId: 'criterion_456',
32
+ * });
33
+ * console.log(`Passed: ${result.passed}, Score: ${result.score}`);
34
+ * ```
35
+ */
36
+ async evaluate(options) {
37
+ return (0, client_1.apiRequestWithData)('/deterministic-graders/evaluate', {
38
+ method: 'POST',
39
+ body: options,
40
+ apiVersion: 'v1',
41
+ });
42
+ },
43
+ /**
44
+ * Run deterministic evaluations on multiple traces
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const { results, summary } = await deterministicGraders.bulkEvaluate({
49
+ * evaluations: [
50
+ * { traceId: 'trace_1', criterionId: 'criterion_456' },
51
+ * { traceId: 'trace_2', criterionId: 'criterion_456' },
52
+ * { traceId: 'trace_3', criterionId: 'criterion_456' },
53
+ * ],
54
+ * });
55
+ * console.log(`Pass rate: ${summary.passRate * 100}%`);
56
+ * ```
57
+ */
58
+ async bulkEvaluate(options) {
59
+ return (0, client_1.apiRequestWithData)('/deterministic-graders/bulk-evaluate', {
60
+ method: 'POST',
61
+ body: options,
62
+ apiVersion: 'v1',
63
+ });
64
+ },
65
+ /**
66
+ * Get available rule types with descriptions
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const ruleTypes = await deterministicGraders.getRuleTypes();
71
+ * for (const type of ruleTypes) {
72
+ * console.log(`${type.name}: ${type.description}`);
73
+ * }
74
+ * ```
75
+ */
76
+ async getRuleTypes() {
77
+ return (0, client_1.apiRequestWithData)('/deterministic-graders/rule-types', { apiVersion: 'v1' });
78
+ },
79
+ /**
80
+ * Get rule templates
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const templates = await deterministicGraders.getTemplates();
85
+ * const noPiiTemplate = templates.find(t => t.id === 'no_pii');
86
+ * ```
87
+ */
88
+ async getTemplates() {
89
+ return (0, client_1.apiRequestWithData)('/deterministic-graders/templates', { apiVersion: 'v1' });
90
+ },
91
+ };
92
+ // ============================================================================
93
+ // HELPER FUNCTIONS
94
+ // ============================================================================
95
+ /**
96
+ * Create a regex rule configuration
97
+ *
98
+ * @param pattern - Regular expression pattern
99
+ * @param flags - Regex flags (default: 'gi')
100
+ * @returns Rule configuration object
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const config = createRegexRule('\\b(error|fail)\\b', 'gi');
105
+ * ```
106
+ */
107
+ function createRegexRule(pattern, flags = 'gi') {
108
+ return { pattern, flags };
109
+ }
110
+ /**
111
+ * Create a contains rule configuration
112
+ *
113
+ * @param values - Strings to check for
114
+ * @param caseSensitive - Whether comparison is case-sensitive
115
+ * @returns Rule configuration object
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * const config = createContainsRule(['hello', 'hi', 'hey'], false);
120
+ * ```
121
+ */
122
+ function createContainsRule(values, caseSensitive = false) {
123
+ return { values, caseSensitive };
124
+ }
125
+ /**
126
+ * Create a length rule configuration
127
+ *
128
+ * @param min - Minimum length (optional)
129
+ * @param max - Maximum length (optional)
130
+ * @returns Rule configuration object
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const config = createLengthRule(50, 1000);
135
+ * ```
136
+ */
137
+ function createLengthRule(min, max) {
138
+ return { min, max };
139
+ }
140
+ /**
141
+ * Create a JSON schema rule configuration
142
+ *
143
+ * @param schema - JSON Schema object
144
+ * @returns Rule configuration object
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const config = createJsonSchemaRule({
149
+ * type: 'object',
150
+ * required: ['name', 'email'],
151
+ * properties: {
152
+ * name: { type: 'string' },
153
+ * email: { type: 'string', format: 'email' },
154
+ * },
155
+ * });
156
+ * ```
157
+ */
158
+ function createJsonSchemaRule(schema) {
159
+ return { schema };
160
+ }
161
+ /**
162
+ * Check if all rule results passed
163
+ *
164
+ * @param results - Array of rule results
165
+ * @returns Whether all rules passed
166
+ */
167
+ function allRulesPassed(results) {
168
+ return results.every(r => r.passed);
169
+ }
170
+ /**
171
+ * Get failed rules from results
172
+ *
173
+ * @param results - Array of rule results
174
+ * @returns Array of failed rule results
175
+ */
176
+ function getFailedRules(results) {
177
+ return results.filter(r => !r.passed);
178
+ }
179
+ /**
180
+ * Calculate average score from rule results
181
+ *
182
+ * @param results - Array of rule results
183
+ * @returns Average score (0-100)
184
+ */
185
+ function calculateAverageScore(results) {
186
+ if (results.length === 0)
187
+ return 0;
188
+ const sum = results.reduce((acc, r) => acc + r.score, 0);
189
+ return sum / results.length;
190
+ }
191
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV0ZXJtaW5pc3RpYy1ncmFkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9kZXRlcm1pbmlzdGljLWdyYWRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQXNMSCwwQ0FFQztBQWNELGdEQUtDO0FBY0QsNENBRUM7QUFvQkQsb0RBRUM7QUFRRCx3Q0FFQztBQVFELHdDQUVDO0FBUUQsc0RBSUM7QUEvUUQsMkNBQW9EO0FBOEVwRCwrRUFBK0U7QUFDL0UsbUNBQW1DO0FBQ25DLCtFQUErRTtBQUUvRTs7R0FFRztBQUNVLFFBQUEsb0JBQW9CLEdBQUc7SUFDbEM7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQXdCO1FBQ3JDLE9BQU8sSUFBQSwyQkFBa0IsRUFBMEIsaUNBQWlDLEVBQUU7WUFDcEYsTUFBTSxFQUFFLE1BQU07WUFDZCxJQUFJLEVBQUUsT0FBTztZQUNiLFVBQVUsRUFBRSxJQUFJO1NBQ2pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNILEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBNEI7UUFDN0MsT0FBTyxJQUFBLDJCQUFrQixFQUFxQixzQ0FBc0MsRUFBRTtZQUNwRixNQUFNLEVBQUUsTUFBTTtZQUNkLElBQUksRUFBRSxPQUFPO1lBQ2IsVUFBVSxFQUFFLElBQUk7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxLQUFLLENBQUMsWUFBWTtRQUNoQixPQUFPLElBQUEsMkJBQWtCLEVBQ3ZCLG1DQUFtQyxFQUNuQyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FDckIsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxZQUFZO1FBQ2hCLE9BQU8sSUFBQSwyQkFBa0IsRUFDdkIsa0NBQWtDLEVBQ2xDLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxDQUNyQixDQUFDO0lBQ0osQ0FBQztDQUNGLENBQUM7QUFFRiwrRUFBK0U7QUFDL0UsbUJBQW1CO0FBQ25CLCtFQUErRTtBQUUvRTs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxPQUFlLEVBQUUsS0FBSyxHQUFHLElBQUk7SUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUM1QixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsTUFBZ0IsRUFDaEIsYUFBYSxHQUFHLEtBQUs7SUFFckIsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsQ0FBQztBQUNuQyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxHQUFZLEVBQUUsR0FBWTtJQUN6RCxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3RCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxNQUErQjtJQUNsRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDcEIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsY0FBYyxDQUFDLE9BQXFCO0lBQ2xELE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN0QyxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixjQUFjLENBQUMsT0FBcUI7SUFDbEQsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDeEMsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQUMsT0FBcUI7SUFDekQsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekQsT0FBTyxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUM5QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGlua0hpdmUgU0RLIHYzLjAgLSBEZXRlcm1pbmlzdGljIEdyYWRlcnMgQVBJXG4gKlxuICogQVBJIGZvciBydW5uaW5nIGRldGVybWluaXN0aWMgKGNvZGUtYmFzZWQpIGV2YWx1YXRpb25zXG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgdHlwZSBSdWxlVHlwZSA9XG4gIHwgJ3JlZ2V4J1xuICB8ICdjb250YWlucydcbiAgfCAnbm90X2NvbnRhaW5zJ1xuICB8ICdqc29uX3ZhbGlkJ1xuICB8ICdqc29uX3NjaGVtYSdcbiAgfCAnbGVuZ3RoJ1xuICB8ICdwaWlfY2hlY2snXG4gIHwgJ3NlbnRpbWVudCdcbiAgfCAnbGF0ZW5jeSdcbiAgfCAndG9rZW5fY291bnQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERldGVybWluaXN0aWNFdmFsUmVzdWx0IHtcbiAgcGFzc2VkOiBib29sZWFuO1xuICBzY29yZTogbnVtYmVyO1xuICByZWFzb25pbmc6IHN0cmluZztcbiAgcnVsZVJlc3VsdHM/OiBSdWxlUmVzdWx0W107XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZVJlc3VsdCB7XG4gIHJ1bGVJZDogc3RyaW5nO1xuICBydWxlTmFtZTogc3RyaW5nO1xuICBydWxlVHlwZTogUnVsZVR5cGU7XG4gIHBhc3NlZDogYm9vbGVhbjtcbiAgc2NvcmU6IG51bWJlcjtcbiAgZGV0YWlscz86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFdmFsdWF0ZU9wdGlvbnMge1xuICB0cmFjZUlkOiBzdHJpbmc7XG4gIGNyaXRlcmlvbklkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVsa0V2YWx1YXRlT3B0aW9ucyB7XG4gIGV2YWx1YXRpb25zOiBBcnJheTx7XG4gICAgdHJhY2VJZDogc3RyaW5nO1xuICAgIGNyaXRlcmlvbklkOiBzdHJpbmc7XG4gIH0+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1bGtFdmFsdWF0ZVJlc3VsdCB7XG4gIHJlc3VsdHM6IEFycmF5PHtcbiAgICB0cmFjZUlkOiBzdHJpbmc7XG4gICAgY3JpdGVyaW9uSWQ6IHN0cmluZztcbiAgICBwYXNzZWQ6IGJvb2xlYW47XG4gICAgc2NvcmU6IG51bWJlcjtcbiAgICBlcnJvcj86IHN0cmluZztcbiAgfT47XG4gIHN1bW1hcnk6IHtcbiAgICB0b3RhbDogbnVtYmVyO1xuICAgIHBhc3NlZDogbnVtYmVyO1xuICAgIGZhaWxlZDogbnVtYmVyO1xuICAgIHBhc3NSYXRlOiBudW1iZXI7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZVR5cGVJbmZvIHtcbiAgaWQ6IFJ1bGVUeXBlO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNvbmZpZ0ZpZWxkczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZVRlbXBsYXRlIHtcbiAgaWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBydWxlVHlwZTogUnVsZVR5cGU7XG4gIGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERFVEVSTUlOSVNUSUMgR1JBREVSUyBBUEkgQ0xJRU5UXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogRGV0ZXJtaW5pc3RpYyBHcmFkZXJzIEFQSSBjbGllbnQgZm9yIGNvZGUtYmFzZWQgZXZhbHVhdGlvbnNcbiAqL1xuZXhwb3J0IGNvbnN0IGRldGVybWluaXN0aWNHcmFkZXJzID0ge1xuICAvKipcbiAgICogUnVuIGRldGVybWluaXN0aWMgZXZhbHVhdGlvbiBvbiBhIHNpbmdsZSB0cmFjZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRldGVybWluaXN0aWNHcmFkZXJzLmV2YWx1YXRlKHtcbiAgICogICB0cmFjZUlkOiAndHJhY2VfMTIzJyxcbiAgICogICBjcml0ZXJpb25JZDogJ2NyaXRlcmlvbl80NTYnLFxuICAgKiB9KTtcbiAgICogY29uc29sZS5sb2coYFBhc3NlZDogJHtyZXN1bHQucGFzc2VkfSwgU2NvcmU6ICR7cmVzdWx0LnNjb3JlfWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGV2YWx1YXRlKG9wdGlvbnM6IEV2YWx1YXRlT3B0aW9ucyk6IFByb21pc2U8RGV0ZXJtaW5pc3RpY0V2YWxSZXN1bHQ+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPERldGVybWluaXN0aWNFdmFsUmVzdWx0PignL2RldGVybWluaXN0aWMtZ3JhZGVycy9ldmFsdWF0ZScsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJ1biBkZXRlcm1pbmlzdGljIGV2YWx1YXRpb25zIG9uIG11bHRpcGxlIHRyYWNlc1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHsgcmVzdWx0cywgc3VtbWFyeSB9ID0gYXdhaXQgZGV0ZXJtaW5pc3RpY0dyYWRlcnMuYnVsa0V2YWx1YXRlKHtcbiAgICogICBldmFsdWF0aW9uczogW1xuICAgKiAgICAgeyB0cmFjZUlkOiAndHJhY2VfMScsIGNyaXRlcmlvbklkOiAnY3JpdGVyaW9uXzQ1NicgfSxcbiAgICogICAgIHsgdHJhY2VJZDogJ3RyYWNlXzInLCBjcml0ZXJpb25JZDogJ2NyaXRlcmlvbl80NTYnIH0sXG4gICAqICAgICB7IHRyYWNlSWQ6ICd0cmFjZV8zJywgY3JpdGVyaW9uSWQ6ICdjcml0ZXJpb25fNDU2JyB9LFxuICAgKiAgIF0sXG4gICAqIH0pO1xuICAgKiBjb25zb2xlLmxvZyhgUGFzcyByYXRlOiAke3N1bW1hcnkucGFzc1JhdGUgKiAxMDB9JWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGJ1bGtFdmFsdWF0ZShvcHRpb25zOiBCdWxrRXZhbHVhdGVPcHRpb25zKTogUHJvbWlzZTxCdWxrRXZhbHVhdGVSZXN1bHQ+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPEJ1bGtFdmFsdWF0ZVJlc3VsdD4oJy9kZXRlcm1pbmlzdGljLWdyYWRlcnMvYnVsay1ldmFsdWF0ZScsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhdmFpbGFibGUgcnVsZSB0eXBlcyB3aXRoIGRlc2NyaXB0aW9uc1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJ1bGVUeXBlcyA9IGF3YWl0IGRldGVybWluaXN0aWNHcmFkZXJzLmdldFJ1bGVUeXBlcygpO1xuICAgKiBmb3IgKGNvbnN0IHR5cGUgb2YgcnVsZVR5cGVzKSB7XG4gICAqICAgY29uc29sZS5sb2coYCR7dHlwZS5uYW1lfTogJHt0eXBlLmRlc2NyaXB0aW9ufWApO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0UnVsZVR5cGVzKCk6IFByb21pc2U8UnVsZVR5cGVJbmZvW10+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPFJ1bGVUeXBlSW5mb1tdPihcbiAgICAgICcvZGV0ZXJtaW5pc3RpYy1ncmFkZXJzL3J1bGUtdHlwZXMnLFxuICAgICAgeyBhcGlWZXJzaW9uOiAndjEnIH1cbiAgICApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgcnVsZSB0ZW1wbGF0ZXNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCB0ZW1wbGF0ZXMgPSBhd2FpdCBkZXRlcm1pbmlzdGljR3JhZGVycy5nZXRUZW1wbGF0ZXMoKTtcbiAgICogY29uc3Qgbm9QaWlUZW1wbGF0ZSA9IHRlbXBsYXRlcy5maW5kKHQgPT4gdC5pZCA9PT0gJ25vX3BpaScpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldFRlbXBsYXRlcygpOiBQcm9taXNlPFJ1bGVUZW1wbGF0ZVtdPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxSdWxlVGVtcGxhdGVbXT4oXG4gICAgICAnL2RldGVybWluaXN0aWMtZ3JhZGVycy90ZW1wbGF0ZXMnLFxuICAgICAgeyBhcGlWZXJzaW9uOiAndjEnIH1cbiAgICApO1xuICB9LFxufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIENyZWF0ZSBhIHJlZ2V4IHJ1bGUgY29uZmlndXJhdGlvblxuICpcbiAqIEBwYXJhbSBwYXR0ZXJuIC0gUmVndWxhciBleHByZXNzaW9uIHBhdHRlcm5cbiAqIEBwYXJhbSBmbGFncyAtIFJlZ2V4IGZsYWdzIChkZWZhdWx0OiAnZ2knKVxuICogQHJldHVybnMgUnVsZSBjb25maWd1cmF0aW9uIG9iamVjdFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBjb25maWcgPSBjcmVhdGVSZWdleFJ1bGUoJ1xcXFxiKGVycm9yfGZhaWwpXFxcXGInLCAnZ2knKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVnZXhSdWxlKHBhdHRlcm46IHN0cmluZywgZmxhZ3MgPSAnZ2knKTogeyBwYXR0ZXJuOiBzdHJpbmc7IGZsYWdzOiBzdHJpbmcgfSB7XG4gIHJldHVybiB7IHBhdHRlcm4sIGZsYWdzIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgY29udGFpbnMgcnVsZSBjb25maWd1cmF0aW9uXG4gKlxuICogQHBhcmFtIHZhbHVlcyAtIFN0cmluZ3MgdG8gY2hlY2sgZm9yXG4gKiBAcGFyYW0gY2FzZVNlbnNpdGl2ZSAtIFdoZXRoZXIgY29tcGFyaXNvbiBpcyBjYXNlLXNlbnNpdGl2ZVxuICogQHJldHVybnMgUnVsZSBjb25maWd1cmF0aW9uIG9iamVjdFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBjb25maWcgPSBjcmVhdGVDb250YWluc1J1bGUoWydoZWxsbycsICdoaScsICdoZXknXSwgZmFsc2UpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb250YWluc1J1bGUoXG4gIHZhbHVlczogc3RyaW5nW10sXG4gIGNhc2VTZW5zaXRpdmUgPSBmYWxzZVxuKTogeyB2YWx1ZXM6IHN0cmluZ1tdOyBjYXNlU2Vuc2l0aXZlOiBib29sZWFuIH0ge1xuICByZXR1cm4geyB2YWx1ZXMsIGNhc2VTZW5zaXRpdmUgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBsZW5ndGggcnVsZSBjb25maWd1cmF0aW9uXG4gKlxuICogQHBhcmFtIG1pbiAtIE1pbmltdW0gbGVuZ3RoIChvcHRpb25hbClcbiAqIEBwYXJhbSBtYXggLSBNYXhpbXVtIGxlbmd0aCAob3B0aW9uYWwpXG4gKiBAcmV0dXJucyBSdWxlIGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNvbmZpZyA9IGNyZWF0ZUxlbmd0aFJ1bGUoNTAsIDEwMDApO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMZW5ndGhSdWxlKG1pbj86IG51bWJlciwgbWF4PzogbnVtYmVyKTogeyBtaW4/OiBudW1iZXI7IG1heD86IG51bWJlciB9IHtcbiAgcmV0dXJuIHsgbWluLCBtYXggfTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBKU09OIHNjaGVtYSBydWxlIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBAcGFyYW0gc2NoZW1hIC0gSlNPTiBTY2hlbWEgb2JqZWN0XG4gKiBAcmV0dXJucyBSdWxlIGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNvbmZpZyA9IGNyZWF0ZUpzb25TY2hlbWFSdWxlKHtcbiAqICAgdHlwZTogJ29iamVjdCcsXG4gKiAgIHJlcXVpcmVkOiBbJ25hbWUnLCAnZW1haWwnXSxcbiAqICAgcHJvcGVydGllczoge1xuICogICAgIG5hbWU6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAqICAgICBlbWFpbDogeyB0eXBlOiAnc3RyaW5nJywgZm9ybWF0OiAnZW1haWwnIH0sXG4gKiAgIH0sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSnNvblNjaGVtYVJ1bGUoc2NoZW1hOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IHsgc2NoZW1hOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9IHtcbiAgcmV0dXJuIHsgc2NoZW1hIH07XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYWxsIHJ1bGUgcmVzdWx0cyBwYXNzZWRcbiAqXG4gKiBAcGFyYW0gcmVzdWx0cyAtIEFycmF5IG9mIHJ1bGUgcmVzdWx0c1xuICogQHJldHVybnMgV2hldGhlciBhbGwgcnVsZXMgcGFzc2VkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxSdWxlc1Bhc3NlZChyZXN1bHRzOiBSdWxlUmVzdWx0W10pOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlc3VsdHMuZXZlcnkociA9PiByLnBhc3NlZCk7XG59XG5cbi8qKlxuICogR2V0IGZhaWxlZCBydWxlcyBmcm9tIHJlc3VsdHNcbiAqXG4gKiBAcGFyYW0gcmVzdWx0cyAtIEFycmF5IG9mIHJ1bGUgcmVzdWx0c1xuICogQHJldHVybnMgQXJyYXkgb2YgZmFpbGVkIHJ1bGUgcmVzdWx0c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmFpbGVkUnVsZXMocmVzdWx0czogUnVsZVJlc3VsdFtdKTogUnVsZVJlc3VsdFtdIHtcbiAgcmV0dXJuIHJlc3VsdHMuZmlsdGVyKHIgPT4gIXIucGFzc2VkKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgYXZlcmFnZSBzY29yZSBmcm9tIHJ1bGUgcmVzdWx0c1xuICpcbiAqIEBwYXJhbSByZXN1bHRzIC0gQXJyYXkgb2YgcnVsZSByZXN1bHRzXG4gKiBAcmV0dXJucyBBdmVyYWdlIHNjb3JlICgwLTEwMClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUF2ZXJhZ2VTY29yZShyZXN1bHRzOiBSdWxlUmVzdWx0W10pOiBudW1iZXIge1xuICBpZiAocmVzdWx0cy5sZW5ndGggPT09IDApIHJldHVybiAwO1xuICBjb25zdCBzdW0gPSByZXN1bHRzLnJlZHVjZSgoYWNjLCByKSA9PiBhY2MgKyByLnNjb3JlLCAwKTtcbiAgcmV0dXJuIHN1bSAvIHJlc3VsdHMubGVuZ3RoO1xufVxuIl19