@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,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThinkHive SDK v3.0 - Conversation Evaluation API
|
|
3
|
+
*
|
|
4
|
+
* API for multi-turn conversation evaluation
|
|
5
|
+
*/
|
|
6
|
+
export type AggregateMethod = 'worst' | 'average' | 'weighted' | 'final_turn' | 'majority';
|
|
7
|
+
export interface SessionTrace {
|
|
8
|
+
id: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
turnNumber: number;
|
|
11
|
+
userMessage: string;
|
|
12
|
+
agentResponse: string;
|
|
13
|
+
timestamp: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface TurnEvaluation {
|
|
17
|
+
traceId: string;
|
|
18
|
+
turnNumber: number;
|
|
19
|
+
passed: boolean;
|
|
20
|
+
score: number;
|
|
21
|
+
reasoning: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ConversationEvalResult {
|
|
24
|
+
sessionId: string;
|
|
25
|
+
criterionId: string;
|
|
26
|
+
turnCount: number;
|
|
27
|
+
turnResults: TurnEvaluation[];
|
|
28
|
+
aggregatePassed: boolean;
|
|
29
|
+
aggregateScore: number;
|
|
30
|
+
aggregateMethod: AggregateMethod;
|
|
31
|
+
reasoning: string;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
export interface EvaluateConversationOptions {
|
|
35
|
+
sessionId: string;
|
|
36
|
+
criterionId: string;
|
|
37
|
+
options?: {
|
|
38
|
+
aggregateMethod?: AggregateMethod;
|
|
39
|
+
minTurns?: number;
|
|
40
|
+
maxTurns?: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface AggregationMethodInfo {
|
|
44
|
+
id: AggregateMethod;
|
|
45
|
+
name: string;
|
|
46
|
+
description: string;
|
|
47
|
+
useCase: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Conversation Evaluation API client for multi-turn evaluation
|
|
51
|
+
*/
|
|
52
|
+
export declare const conversationEval: {
|
|
53
|
+
/**
|
|
54
|
+
* Get traces for a conversation session
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const traces = await conversationEval.getSessionTraces('session_123');
|
|
59
|
+
* console.log(`Conversation has ${traces.length} turns`);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
getSessionTraces(sessionId: string): Promise<SessionTrace[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Run conversation-level evaluation
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const result = await conversationEval.evaluate({
|
|
69
|
+
* sessionId: 'session_123',
|
|
70
|
+
* criterionId: 'criterion_456',
|
|
71
|
+
* options: {
|
|
72
|
+
* aggregateMethod: 'average',
|
|
73
|
+
* minTurns: 2,
|
|
74
|
+
* },
|
|
75
|
+
* });
|
|
76
|
+
* console.log(`Conversation score: ${result.aggregateScore}`);
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
evaluate(options: EvaluateConversationOptions): Promise<ConversationEvalResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Get available aggregation methods with descriptions
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const methods = await conversationEval.getAggregationMethods();
|
|
86
|
+
* for (const method of methods) {
|
|
87
|
+
* console.log(`${method.name}: ${method.description}`);
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
getAggregationMethods(): Promise<AggregationMethodInfo[]>;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Calculate worst-turn aggregation
|
|
95
|
+
*
|
|
96
|
+
* @param turnResults - Array of turn evaluation results
|
|
97
|
+
* @returns Aggregated result using worst turn logic
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const result = aggregateWorst(turnResults);
|
|
102
|
+
* // Fails if any turn fails
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function aggregateWorst(turnResults: TurnEvaluation[]): {
|
|
106
|
+
passed: boolean;
|
|
107
|
+
score: number;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Calculate average aggregation
|
|
111
|
+
*
|
|
112
|
+
* @param turnResults - Array of turn evaluation results
|
|
113
|
+
* @returns Aggregated result using average logic
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const result = aggregateAverage(turnResults);
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function aggregateAverage(turnResults: TurnEvaluation[]): {
|
|
121
|
+
passed: boolean;
|
|
122
|
+
score: number;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Calculate weighted average aggregation (later turns weighted more)
|
|
126
|
+
*
|
|
127
|
+
* @param turnResults - Array of turn evaluation results
|
|
128
|
+
* @returns Aggregated result using weighted average logic
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const result = aggregateWeighted(turnResults);
|
|
133
|
+
* // Later turns have higher weight
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export declare function aggregateWeighted(turnResults: TurnEvaluation[]): {
|
|
137
|
+
passed: boolean;
|
|
138
|
+
score: number;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Calculate final-turn aggregation
|
|
142
|
+
*
|
|
143
|
+
* @param turnResults - Array of turn evaluation results
|
|
144
|
+
* @returns Aggregated result using only the final turn
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const result = aggregateFinalTurn(turnResults);
|
|
149
|
+
* // Only final turn matters
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
export declare function aggregateFinalTurn(turnResults: TurnEvaluation[]): {
|
|
153
|
+
passed: boolean;
|
|
154
|
+
score: number;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Calculate majority vote aggregation
|
|
158
|
+
*
|
|
159
|
+
* @param turnResults - Array of turn evaluation results
|
|
160
|
+
* @returns Aggregated result using majority vote logic
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const result = aggregateMajority(turnResults);
|
|
165
|
+
* // Passes if majority of turns pass
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export declare function aggregateMajority(turnResults: TurnEvaluation[]): {
|
|
169
|
+
passed: boolean;
|
|
170
|
+
score: number;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Get appropriate aggregation function for a method
|
|
174
|
+
*
|
|
175
|
+
* @param method - Aggregation method name
|
|
176
|
+
* @returns Aggregation function
|
|
177
|
+
*/
|
|
178
|
+
export declare function getAggregator(method: AggregateMethod): (turnResults: TurnEvaluation[]) => {
|
|
179
|
+
passed: boolean;
|
|
180
|
+
score: number;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Find problematic turns in a conversation
|
|
184
|
+
*
|
|
185
|
+
* @param result - Conversation evaluation result
|
|
186
|
+
* @param scoreThreshold - Minimum acceptable score (default 70)
|
|
187
|
+
* @returns Array of problematic turn results
|
|
188
|
+
*/
|
|
189
|
+
export declare function getProblematicTurns(result: ConversationEvalResult, scoreThreshold?: number): TurnEvaluation[];
|
|
190
|
+
/**
|
|
191
|
+
* Calculate conversation quality trend
|
|
192
|
+
*
|
|
193
|
+
* @param result - Conversation evaluation result
|
|
194
|
+
* @returns Trend analysis
|
|
195
|
+
*/
|
|
196
|
+
export declare function analyzeConversationTrend(result: ConversationEvalResult): {
|
|
197
|
+
direction: 'improving' | 'declining' | 'stable';
|
|
198
|
+
firstHalfAvg: number;
|
|
199
|
+
secondHalfAvg: number;
|
|
200
|
+
};
|
|
@@ -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: 'none' });
|
|
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: 'none',
|
|
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: 'none' });
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVyc2F0aW9uLWV2YWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2NvbnZlcnNhdGlvbi1ldmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7OztHQUlHOzs7QUE0SUgsd0NBT0M7QUFhRCw0Q0FRQztBQWNELDhDQW1CQztBQWNELGdEQUtDO0FBY0QsOENBUUM7QUFRRCxzQ0FXQztBQVNELGtEQUtDO0FBUUQsNERBeUJDO0FBbFRELDJDQUFvRDtBQXVEcEQsK0VBQStFO0FBQy9FLCtCQUErQjtBQUMvQiwrRUFBK0U7QUFFL0U7O0dBRUc7QUFDVSxRQUFBLGdCQUFnQixHQUFHO0lBQzlCOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUFDLFNBQWlCO1FBQ3RDLE9BQU8sSUFBQSwyQkFBa0IsRUFDdkIsdUNBQXVDLFNBQVMsRUFBRSxFQUNsRCxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FDdkIsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQW9DO1FBQ2pELE9BQU8sSUFBQSwyQkFBa0IsRUFBeUIsNkJBQTZCLEVBQUU7WUFDL0UsTUFBTSxFQUFFLE1BQU07WUFDZCxJQUFJLEVBQUUsT0FBTztZQUNiLFVBQVUsRUFBRSxNQUFNO1NBQ25CLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQjtRQUN6QixPQUFPLElBQUEsMkJBQWtCLEVBQ3ZCLHdDQUF3QyxFQUN4QyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FDdkIsQ0FBQztJQUNKLENBQUM7Q0FDRixDQUFDO0FBRUYsK0VBQStFO0FBQy9FLG1CQUFtQjtBQUNuQiwrRUFBK0U7QUFFL0U7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixjQUFjLENBQUMsV0FBNkI7SUFDMUQsSUFBSSxXQUFXLENB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QU0sSUFBSSxHQUFHLGFBQWEsR0FBRyxZQUFZLENBQUM7SUFDMUMsSUFBSSxTQUErQyxDQUFDO0lBRXBELElBQUksSUFBSSxHQUFHLENBQUM7UUFBRSxTQUFTLEdBQUcsV0FBVyxDQUFDO1NBQ2pDLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQztRQUFFLFNBQVMsR0FBRyxXQUFXLENBQUM7O1FBQ3ZDLFNBQVMsR0FBRyxRQUFRLENBQUM7SUFFMUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLENBQUM7QUFDcEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhpbmtIaXZlIFNESyB2My4wIC0gQ29udmVyc2F0aW9uIEV2YWx1YXRpb24gQVBJXG4gKlxuICogQVBJIGZvciBtdWx0aS10dXJuIGNvbnZlcnNhdGlvbiBldmFsdWF0aW9uXG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgdHlwZSBBZ2dyZWdhdGVNZXRob2QgPSAnd29yc3QnIHwgJ2F2ZXJhZ2UnIHwgJ3dlaWdodGVkJyB8ICdmaW5hbF90dXJuJyB8ICdtYWpvcml0eSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvblRyYWNlIHtcbiAgaWQ6IHN0cmluZztcbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIHR1cm5OdW1iZXI6IG51bWJlcjtcbiAgdXNlck1lc3NhZ2U6IHN0cmluZztcbiAgYWdlbnRSZXNwb25zZTogc3RyaW5nO1xuICB0aW1lc3RhbXA6IHN0cmluZztcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUdXJuRXZhbHVhdGlvbiB7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgdHVybk51bWJlcjogbnVtYmVyO1xuICBwYXNzZWQ6IGJvb2xlYW47XG4gIHNjb3JlOiBudW1iZXI7XG4gIHJlYXNvbmluZzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZlcnNhdGlvbkV2YWxSZXN1bHQge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ6IHN0cmluZztcbiAgdHVybkNvdW50OiBudW1iZXI7XG4gIHR1cm5SZXN1bHRzOiBUdXJuRXZhbHVhdGlvbltdO1xuICBhZ2dyZWdhdGVQYXNzZWQ6IGJvb2xlYW47XG4gIGFnZ3JlZ2F0ZVNjb3JlOiBudW1iZXI7XG4gIGFnZ3JlZ2F0ZU1ldGhvZDogQWdncmVnYXRlTWV0aG9kO1xuICByZWFzb25pbmc6IHN0cmluZztcbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFdmFsdWF0ZUNvbnZlcnNhdGlvbk9wdGlvbnMge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ6IHN0cmluZztcbiAgb3B0aW9ucz86IHtcbiAgICBhZ2dyZWdhdGVNZXRob2Q/OiBBZ2dyZWdhdGVNZXRob2Q7XG4gICAgbWluVHVybnM/OiBudW1iZXI7XG4gICAgbWF4VHVybnM/OiBudW1iZXI7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWdncmVnYXRpb25NZXRob2RJbmZvIHtcbiAgaWQ6IEFnZ3JlZ2F0ZU1ldGhvZDtcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB1c2VDYXNlOiBzdHJpbmc7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENPTlZFUlNBVElPTiBFVkFMIEFQSSBDTElFTlRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDb252ZXJzYXRpb24gRXZhbHVhdGlvbiBBUEkgY2xpZW50IGZvciBtdWx0aS10dXJuIGV2YWx1YXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnZlcnNhdGlvbkV2YWwgPSB7XG4gIC8qKlxuICAgKiBHZXQgdHJhY2VzIGZvciBhIGNvbnZlcnNhdGlvbiBzZXNzaW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgdHJhY2VzID0gYXdhaXQgY29udmVyc2F0aW9uRXZhbC5nZXRTZXNzaW9uVHJhY2VzKCdzZXNzaW9uXzEyMycpO1xuICAgKiBjb25zb2xlLmxvZyhgQ29udmVyc2F0aW9uIGhhcyAke3RyYWNlcy5sZW5ndGh9IHR1cm5zYCk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0U2Vzc2lvblRyYWNlcyhzZXNzaW9uSWQ6IHN0cmluZyk6IFByb21pc2U8U2Vzc2lvblRyYWNlW10+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPFNlc3Npb25UcmFjZVtdPihcbiAgICAgIGAvY29udmVyc2F0aW9uLWV2YWwvdHJhY2VzP3Nlc3Npb25JZD0ke3Nlc3Npb25JZH1gLFxuICAgICAgeyBhcGlWZXJzaW9uOiAnbm9uZScgfVxuICAgICk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJ1biBjb252ZXJzYXRpb24tbGV2ZWwgZXZhbHVhdGlvblxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbnZlcnNhdGlvbkV2YWwuZXZhbHVhdGUoe1xuICAgKiAgIHNlc3Npb25JZDogJ3Nlc3Npb25fMTIzJyxcbiAgICogICBjcml0ZXJpb25JZDogJ2NyaXRlcmlvbl80NTYnLFxuICAgKiAgIG9wdGlvbnM6IHtcbiAgICogICAgIGFnZ3JlZ2F0ZU1ldGhvZDogJ2F2ZXJhZ2UnLFxuICAgKiAgICAgbWluVHVybnM6IDIsXG4gICAqICAgfSxcbiAgICogfSk7XG4gICAqIGNvbnNvbGUubG9nKGBDb252ZXJzYXRpb24gc2NvcmU6ICR7cmVzdWx0LmFnZ3JlZ2F0ZVNjb3JlfWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGV2YWx1YXRlKG9wdGlvbnM6IEV2YWx1YXRlQ29udmVyc2F0aW9uT3B0aW9ucyk6IFByb21pc2U8Q29udmVyc2F0aW9uRXZhbFJlc3VsdD4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8Q29udmVyc2F0aW9uRXZhbFJlc3VsdD4oJy9jb252ZXJzYXRpb24tZXZhbC9ldmFsdWF0ZScsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIGFwaVZlcnNpb246ICdub25lJyxcbiAgICB9KTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGF2YWlsYWJsZSBhZ2dyZWdhdGlvbiBtZXRob2RzIHdpdGggZGVzY3JpcHRpb25zXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgbWV0aG9kcyA9IGF3YWl0IGNvbnZlcnNhdGlvbkV2YWwuZ2V0QWdncmVnYXRpb25NZXRob2RzKCk7XG4gICAqIGZvciAoY29uc3QgbWV0aG9kIG9mIG1ldGhvZHMpIHtcbiAgICogICBjb25zb2xlLmxvZyhgJHttZXRob2QubmFtZX06ICR7bWV0aG9kLmRlc2NyaXB0aW9ufWApO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0QWdncmVnYXRpb25NZXRob2RzKCk6IFByb21pc2U8QWdncmVnYXRpb25NZXRob2RJbmZvW10+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPEFnZ3JlZ2F0aW9uTWV0aG9kSW5mb1tdPihcbiAgICAgICcvY29udmVyc2F0aW9uLWV2YWwvYWdncmVnYXRpb24tbWV0aG9kcycsXG4gICAgICB7IGFwaVZlcnNpb246ICdub25lJyB9XG4gICAgKTtcbiAgfSxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDYWxjdWxhdGUgd29yc3QtdHVybiBhZ2dyZWdhdGlvblxuICpcbiAqIEBwYXJhbSB0dXJuUmVzdWx0cyAtIEFycmF5IG9mIHR1cm4gZXZhbHVhdGlvbiByZXN1bHRzXG4gKiBAcmV0dXJucyBBZ2dyZWdhdGVkIHJlc3VsdCB1c2luZyB3b3JzdCB0dXJuIGxvZ2ljXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdCA9IGFnZ3JlZ2F0ZVdvcnN0KHR1cm5SZXN1bHRzKTtcbiAqIC8vIEZhaWxzIGlmIGFueSB0dXJuIGZhaWxzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFnZ3JlZ2F0ZVdvcnN0KHR1cm5SZXN1bHRzOiBUdXJuRXZhbHVhdGlvbltdKTogeyBwYXNzZWQ6IGJvb2xlYW47IHNjb3JlOiBudW1iZXIgfSB7XG4gIGlmICh0dXJuUmVzdWx0cy5sZW5ndGggPT09IDApIHJldHVybiB7IHBhc3NlZDogZmFsc2UsIHNjb3JlOiAwIH07XG5cbiAgY29uc3Qgd29yc3RTY29yZSA9IE1hdGgubWluKC4uLnR1cm5SZXN1bHRzLm1hcCh0ID0+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;
|