@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,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ThinkHive SDK v3.1 - Quality Metrics API
|
|
4
|
+
*
|
|
5
|
+
* RAG Evaluation & Hallucination Detection for AI quality assurance
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.qualityMetrics = void 0;
|
|
9
|
+
exports.passesQualityThreshold = passesQualityThreshold;
|
|
10
|
+
exports.isHallucinationRiskAcceptable = isHallucinationRiskAcceptable;
|
|
11
|
+
exports.getQualityRecommendations = getQualityRecommendations;
|
|
12
|
+
exports.formatQualityScore = formatQualityScore;
|
|
13
|
+
exports.getGradeColor = getGradeColor;
|
|
14
|
+
const client_1 = require("../core/client");
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// QUALITY METRICS API CLIENT
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Quality Metrics API client for RAG evaluation and hallucination detection
|
|
20
|
+
*/
|
|
21
|
+
exports.qualityMetrics = {
|
|
22
|
+
/**
|
|
23
|
+
* Get RAG quality scores for a specific trace
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const scores = await qualityMetrics.getRagScores('trace_abc123');
|
|
28
|
+
* console.log(`Groundedness: ${scores.evaluation.groundedness}`);
|
|
29
|
+
* console.log(`Grade: ${scores.evaluation.grade}`);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
async getRagScores(traceId) {
|
|
33
|
+
return (0, client_1.apiRequestWithData)(`/quality/rag-scores/${traceId}`, {
|
|
34
|
+
apiVersion: 'v1',
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
/**
|
|
38
|
+
* Get hallucination detection report for a trace
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const report = await qualityMetrics.getHallucinationReport('trace_abc123');
|
|
43
|
+
* if (report.report.hasHallucinations) {
|
|
44
|
+
* console.log(`Risk level: ${report.report.riskLevel}`);
|
|
45
|
+
* for (const instance of report.report.instances) {
|
|
46
|
+
* console.log(`- ${instance.type}: ${instance.text}`);
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
async getHallucinationReport(traceId) {
|
|
52
|
+
return (0, client_1.apiRequestWithData)(`/quality/hallucination-report/${traceId}`, {
|
|
53
|
+
apiVersion: 'v1',
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Evaluate RAG quality for provided content (ad-hoc evaluation)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const result = await qualityMetrics.evaluateRag({
|
|
62
|
+
* query: 'What is the refund policy?',
|
|
63
|
+
* response: 'You can get a refund within 30 days.',
|
|
64
|
+
* retrievedContexts: [
|
|
65
|
+
* { content: 'Our refund policy allows returns within 30 days of purchase.' },
|
|
66
|
+
* ],
|
|
67
|
+
* });
|
|
68
|
+
* console.log(`Groundedness: ${result.evaluation.groundedness}`);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
async evaluateRag(input) {
|
|
72
|
+
return (0, client_1.apiRequestWithData)('/quality/evaluate-rag', {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
body: input,
|
|
75
|
+
apiVersion: 'v1',
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
/**
|
|
79
|
+
* Detect hallucinations in provided content (ad-hoc detection)
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const result = await qualityMetrics.detectHallucinations({
|
|
84
|
+
* response: 'The product costs $99 and comes with a 2-year warranty.',
|
|
85
|
+
* contexts: [
|
|
86
|
+
* { content: 'The product costs $99 with a 1-year warranty.' },
|
|
87
|
+
* ],
|
|
88
|
+
* });
|
|
89
|
+
* if (result.report.hasHallucinations) {
|
|
90
|
+
* console.log('Detected hallucinations:', result.report.instances);
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
async detectHallucinations(input) {
|
|
95
|
+
return (0, client_1.apiRequestWithData)('/quality/detect-hallucinations', {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
body: input,
|
|
98
|
+
apiVersion: 'v1',
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* Get groundedness analysis for a trace
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const result = await qualityMetrics.getGroundedness('trace_abc123');
|
|
107
|
+
* console.log(`Groundedness score: ${result.groundedness.score}`);
|
|
108
|
+
* console.log(`Grounded spans: ${result.summary.groundedSpans}`);
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
async getGroundedness(traceId) {
|
|
112
|
+
return (0, client_1.apiRequestWithData)(`/quality/groundedness/${traceId}`, {
|
|
113
|
+
apiVersion: 'v1',
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* Evaluate multiple traces for quality metrics in batch
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const result = await qualityMetrics.evaluateBatch({
|
|
122
|
+
* traceIds: ['trace_1', 'trace_2', 'trace_3'],
|
|
123
|
+
* });
|
|
124
|
+
* console.log(`Average RAG score: ${result.summary.avgRagScore}`);
|
|
125
|
+
* console.log(`Hallucination rate: ${result.summary.hallucinationRate}%`);
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
async evaluateBatch(options) {
|
|
129
|
+
return (0, client_1.apiRequestWithData)('/quality/evaluate-batch', {
|
|
130
|
+
method: 'POST',
|
|
131
|
+
body: options,
|
|
132
|
+
apiVersion: 'v1',
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
// ============================================================================
|
|
137
|
+
// HELPER FUNCTIONS
|
|
138
|
+
// ============================================================================
|
|
139
|
+
/**
|
|
140
|
+
* Check if a RAG evaluation passes quality thresholds
|
|
141
|
+
*/
|
|
142
|
+
function passesQualityThreshold(evaluation, thresholds = {}) {
|
|
143
|
+
const { minGroundedness = 0.7, minOverallScore = 60, minGrade = 'C' } = thresholds;
|
|
144
|
+
const gradeOrder = { A: 4, B: 3, C: 2, D: 1, F: 0 };
|
|
145
|
+
const meetsGroundedness = evaluation.groundedness >= minGroundedness;
|
|
146
|
+
const meetsScore = evaluation.overallScore >= minOverallScore;
|
|
147
|
+
const meetsGrade = gradeOrder[evaluation.grade] >= gradeOrder[minGrade];
|
|
148
|
+
return meetsGroundedness && meetsScore && meetsGrade;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Check if hallucination risk is acceptable
|
|
152
|
+
*/
|
|
153
|
+
function isHallucinationRiskAcceptable(report, maxRiskLevel = 'medium') {
|
|
154
|
+
const riskOrder = { low: 0, medium: 1, high: 2, critical: 3 };
|
|
155
|
+
return riskOrder[report.riskLevel] <= riskOrder[maxRiskLevel];
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get quality recommendations based on evaluation
|
|
159
|
+
*/
|
|
160
|
+
function getQualityRecommendations(ragEval, hallucinationReport) {
|
|
161
|
+
const recommendations = [];
|
|
162
|
+
if (ragEval.groundedness < 0.7) {
|
|
163
|
+
recommendations.push('Improve grounding by increasing context relevance');
|
|
164
|
+
}
|
|
165
|
+
if (ragEval.contextRelevance < 0.6) {
|
|
166
|
+
recommendations.push('Tune retrieval to return more relevant contexts');
|
|
167
|
+
}
|
|
168
|
+
if (ragEval.citationAccuracy < 0.8) {
|
|
169
|
+
recommendations.push('Improve citation accuracy in responses');
|
|
170
|
+
}
|
|
171
|
+
if (hallucinationReport?.hasHallucinations) {
|
|
172
|
+
recommendations.push('Add fact-checking layer to reduce hallucinations');
|
|
173
|
+
}
|
|
174
|
+
if (recommendations.length === 0) {
|
|
175
|
+
recommendations.push('Quality metrics are within acceptable ranges');
|
|
176
|
+
}
|
|
177
|
+
return recommendations;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Format quality score for display
|
|
181
|
+
*/
|
|
182
|
+
function formatQualityScore(score) {
|
|
183
|
+
return `${Math.round(score * 100)}%`;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get color indicator for grade
|
|
187
|
+
*/
|
|
188
|
+
function getGradeColor(grade) {
|
|
189
|
+
const colors = {
|
|
190
|
+
A: 'green',
|
|
191
|
+
B: 'blue',
|
|
192
|
+
C: 'yellow',
|
|
193
|
+
D: 'orange',
|
|
194
|
+
F: 'red',
|
|
195
|
+
};
|
|
196
|
+
return colors[grade];
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVhbGl0eS1tZXRyaWNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9xdWFsaXR5LW1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQXFWSCx3REFnQkM7QUFLRCxzRUFNQztBQUtELDhEQTJCQztBQUtELGdEQUVDO0FBS0Qsc0NBV0M7QUFyYUQsMkNBQWdFO0FBa0toRSwrRUFBK0U7QUFDL0UsNkJBQTZCO0FBQzdCLCtFQUErRTtBQUUvRTs7R0FFRztBQUNVLFFBQUEsY0FBYyxHQUFHO0lBQzVCOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBZTtRQUtoQyxPQUFPLElBQUEsMkJBQWtCLEVBQUMsdUJBQXVCLE9BQU8sRUFBRSxFQUFFO1lBQzFELFVBQVUsRUFBRSxJQUFJO1NBQ2pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsS0FBSyxDQUFDLHNCQUFzQixDQUFDLE9BQWU7UUFJMUMsT0FBTyxJQUFBLDJCQUFrQixFQUFDLGlDQUFpQyxPQUFPLEVBQUUsRUFBRTtZQUNwRSxVQUFVLEVBQUUsSUFBSTtTQUNqQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLEtBTWpCO1FBSUMsT0FBTyxJQUFBLDJCQUFrQixFQUFDLHVCQUF1QixFQUFFO1lBQ2pELE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLEtBQUs7WUFDWCxVQUFVLEVBQUUsSUFBSTtTQUNqQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsS0FBSyxDQUFDLG9CQUFvQixDQUFDLEtBSzFCO1FBR0MsT0FBTyxJQUFBLDJCQUFrQixFQUFDLGdDQUFnQyxFQUFFO1lBQzFELE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLEtBQUs7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O0dBRUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxLQUFhO0lBQzlDLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDO0FBQ3ZDLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGFBQWEsQ0FDM0IsS0FBa0M7SUFFbEMsTUFBTSxNQUFNLEdBQUc7UUFDYixDQUFDLEVBQUUsT0FBZ0I7UUFDbkIsQ0FBQyxFQUFFLE1BQWU7UUFDbEIsQ0FBQyxFQUFFLFFBQWlCO1FBQ3BCLENBQUMsRUFBRSxRQUFpQjtRQUNwQixDQUFDLEVBQUUsS0FBYztLQUNsQixDQUFDO0lBQ0YsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhpbmtIaXZlIFNESyB2My4xIC0gUXVhbGl0eSBNZXRyaWNzIEFQSVxuICpcbiAqIFJBRyBFdmFsdWF0aW9uICYgSGFsbHVjaW5hdGlvbiBEZXRlY3Rpb24gZm9yIEFJIHF1YWxpdHkgYXNzdXJhbmNlXG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdCwgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuaW1wb3J0IHR5cGUgeyBBcGlSZXNwb25zZSB9IGZyb20gJy4uL2NvcmUvdHlwZXMnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFJldHJpZXZlZCBjb250ZXh0IGZvciBSQUcgZXZhbHVhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJldHJpZXZlZENvbnRleHQge1xuICBjb250ZW50OiBzdHJpbmc7XG4gIGNodW5rSW5kZXg/OiBudW1iZXI7XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIHNjb3JlPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEdyb3VuZCB0cnV0aCBjb250ZXh0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR3JvdW5kVHJ1dGhDb250ZXh0IHtcbiAgY29udGVudDogc3RyaW5nO1xuICBjaHVua0luZGV4PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEdyb3VuZGVkIHNwYW4gZXZpZGVuY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcm91bmRlZFNwYW4ge1xuICB0ZXh0OiBzdHJpbmc7XG4gIGNvbmZpZGVuY2U6IG51bWJlcjtcbiAgc291cmNlQ2h1bmtJbmRleD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBVbmdyb3VuZGVkIHNwYW4gZXZpZGVuY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmdyb3VuZGVkU3BhbiB7XG4gIHRleHQ6IHN0cmluZztcbiAgY29uZmlkZW5jZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIENpdGF0aW9uIG1hcHBpbmdcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDaXRhdGlvbk1hcCB7XG4gIGNsYWltOiBzdHJpbmc7XG4gIGNpdGVkSW5kZXg6IG51bWJlcjtcbiAgaXNWYWxpZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSQUcgZXZhbHVhdGlvbiByZXN1bHRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSQUdFdmFsdWF0aW9uIHtcbiAgLy8gUmV0cmlldmFsIFF1YWxpdHlcbiAgY29udGV4dFJlbGV2YW5jZTogbnVtYmVyO1xuICBjb250ZXh0UHJlY2lzaW9uOiBudW1iZXI7XG4gIGNvbnRleHRSZWNhbGw6IG51bWJlcjtcblxuICAvLyBHZW5lcmF0aW9uIFF1YWxpdHlcbiAgZ3JvdW5kZWRuZXNzOiBudW1iZXI7XG4gIGZhaXRoZnVsbmVzczogbnVtYmVyO1xuICBhbnN3ZXJSZWxldmFuY2U6IG51bWJlcjtcblxuICAvLyBDaXRhdGlvbiBRdWFsaXR5XG4gIGNpdGF0aW9uQWNjdXJhY3k6IG51bWJlcjtcbiAgY2l0YXRpb25Db21wbGV0ZW5lc3M6IG51bWJlcjtcblxuICAvLyBPdmVyYWxsXG4gIG92ZXJhbGxTY29yZTogbnVtYmVyO1xuICBncmFkZTogJ0EnIHwgJ0InIHwgJ0MnIHwgJ0QnIHwgJ0YnO1xuXG4gIC8vIERldGFpbHNcbiAgZ3JvdW5kZWRTcGFuQ291bnQ/OiBudW1iZXI7XG4gIHVuZ3JvdW5kZWRTcGFuQ291bnQ/OiBudW1iZXI7XG4gIGlzc3Vlczogc3RyaW5nW107XG4gIHJlY29tbWVuZGF0aW9uczogc3RyaW5nW107XG59XG5cbi8qKlxuICogUkFHIGV2YWx1YXRpb24gZXZpZGVuY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSQUdFdmlkZW5jZSB7XG4gIGdyb3VuZGVkU3BhbnM6IEdyb3VuZGVkU3BhbltdO1xuICB1bmdyb3VuZGVkU3BhbnM6IFVuZ3JvdW5kZWRTcGFuW107XG4gIGNpdGF0aW9uTWFwOiBDaXRhdGlvbk1hcFtdO1xufVxuXG4vKipcbiAqIEhhbGx1Y2luYXRpb24gaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIYWxsdWNpbmF0aW9uSW5zdGFuY2Uge1xuICB0eXBlOiBzdHJpbmc7XG4gIHNldmVyaXR5OiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnIHwgJ2NyaXRpY2FsJztcbiAgdGV4dDogc3RyaW5nO1xuICBleHBsYW5hdGlvbjogc3RyaW5nO1xuICBjb25maWRlbmNlOiBudW1iZXI7XG4gIHN1Z2dlc3RlZEZpeD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBIYWxsdWNpbmF0aW9uIGRldGVjdGlvbiByZXBvcnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIYWxsdWNpbmF0aW9uUmVwb3J0IHtcbiAgaGFzSGFsbHVjaW5hdGlvbnM6IGJvb2xlYW47XG4gIGhhbGx1Y2luYXRpb25TY29yZTogbnVtYmVyO1xuICByaXNrTGV2ZWw6ICdsb3cnIHwgJ21lZGl1bScgfCAnaGlnaCcgfCAnY3JpdGljYWwnO1xuICBmYWN0dWFsQ2xhaW1zOiBudW1iZXI7XG4gIHZlcmlmaWVkQ2xhaW1zOiBudW1iZXI7XG4gIHVudmVyaWZpZWRDbGFpbXM6IG51bWJlcjtcbiAgc3VtbWFyeTogc3RyaW5nO1xuICByZWNvbW1lbmRhdGlvbnM6IHN0cmluZ1tdO1xuICBpbnN0YW5jZXM6IEhhbGx1Y2luYXRpb25JbnN0YW5jZVtdO1xufVxuXG4vKipcbiAqIEdyb3VuZGVkbmVzcyBhbmFseXNpcyByZXN1bHRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHcm91bmRlZG5lc3NSZXN1bHQge1xuICBzY29yZTogbnVtYmVyO1xuICBmYWl0aGZ1bG5lc3M6IG51bWJlcjtcbiAgY29udGV4dFJlbGV2YW5jZTogbnVtYmVyO1xuICBncmFkZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEJhdGNoIGV2YWx1YXRpb24gcmVzdWx0IGZvciBhIHNpbmdsZSB0cmFjZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhdGNoRXZhbHVhdGlvblJlc3VsdCB7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgc3VjY2VzczogYm9vbGVhbjtcbiAgZXJyb3I/OiBzdHJpbmc7XG4gIHJhZz86IHtcbiAgICBzY29yZTogbnVtYmVyO1xuICAgIGdyYWRlOiBzdHJpbmc7XG4gICAgbWFpbklzc3VlPzogc3RyaW5nO1xuICB9O1xuICBoYWxsdWNpbmF0aW9uPzoge1xuICAgIGhhc0lzc3VlczogYm9vbGVhbjtcbiAgICBzY29yZTogbnVtYmVyO1xuICAgIHRvcElzc3VlPzogc3RyaW5nO1xuICB9O1xufVxuXG4vKipcbiAqIEJhdGNoIGV2YWx1YXRpb24gc3VtbWFyeVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhdGNoRXZhbHVhdGlvblN1bW1hcnkge1xuICB0b3RhbFRyYWNlczogbnVtYmVyO1xuICBzdWNjZXNzZnVsRXZhbHVhdGlvbnM6IG51bWJlcjtcbiAgYXZnUmFnU2NvcmU6IG51bWJlcjtcbiAgaGFsbHVjaW5hdGlvblJhdGU6IG51bWJlcjtcbiAgZ3JhZGVEaXN0cmlidXRpb246IHtcbiAgICBBOiBudW1iZXI7XG4gICAgQjogbnVtYmVyO1xuICAgIEM6IG51bWJlcjtcbiAgICBEOiBudW1iZXI7XG4gICAgRjogbnVtYmVyO1xuICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBRVUFMSVRZIE1FVFJJQ1MgQVBJIENMSUVOVFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFF1YWxpdHkgTWV0cmljcyBBUEkgY2xpZW50IGZvciBSQUcgZXZhbHVhdGlvbiBhbmQgaGFsbHVjaW5hdGlvbiBkZXRlY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHF1YWxpdHlNZXRyaWNzID0ge1xuICAvKipcbiAgICogR2V0IFJBRyBxdWFsaXR5IHNjb3JlcyBmb3IgYSBzcGVjaWZpYyB0cmFjZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHNjb3JlcyA9IGF3YWl0IHF1YWxpdHlNZXRyaWNzLmdldFJhZ1Njb3JlcygndHJhY2VfYWJjMTIzJyk7XG4gICAqIGNvbnNvbGUubG9nKGBHcm91bmRlZG5lc3M6ICR7c2NvcmVzLmV2YWx1YXRpb24uZ3JvdW5kZWRuZXNzfWApO1xuICAgKiBjb25zb2xlLmxvZyhgR3JhZGU6ICR7c2NvcmVzLmV2YWx1YXRpb24uZ3JhZGV9YCk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0UmFnU2NvcmVzKHRyYWNlSWQ6IHN0cmluZyk6IFByb21pc2U8e1xuICAgIHRyYWNlSWQ6IHN0cmluZztcbiAgICBldmFsdWF0aW9uOiBSQUdFdmFsdWF0aW9uO1xuICAgIGV2aWRlbmNlOiBSQUdFdmlkZW5jZTtcbiAgfT4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGEoYC9xdWFsaXR5L3JhZy1zY29yZXMvJHt0cmFjZUlkfWAsIHtcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBoYWxsdWNpbmF0aW9uIGRldGVjdGlvbiByZXBvcnQgZm9yIGEgdHJhY2VcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZXBvcnQgPSBhd2FpdCBxdWFsaXR5TWV0cmljcy5nZXRIYWxsdWNpbmF0aW9uUmVwb3J0KCd0cmFjZV9hYmMxMjMnKTtcbiAgICogaWYgKHJlcG9ydC5yZXBvcnQuaGFzSGFsbHVjaW5hdGlvbnMpIHtcbiAgICogICBjb25zb2xlLmxvZyhgUmlzayBsZXZlbDogJHtyZXBvcnQucmVwb3J0LnJpc2tMZXZlbH1gKTtcbiAgICogICBmb3IgKGNvbnN0IGluc3RhbmNlIG9mIHJlcG9ydC5yZXBvcnQuaW5zdGFuY2VzKSB7XG4gICAqICAgICBjb25zb2xlLmxvZyhgLSAke2luc3RhbmNlLnR5cGV9OiAke2luc3RhbmNlLnRleHR9YCk7XG4gICAqICAgfVxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0SGFsbHVjaW5hdGlvblJlcG9ydCh0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtcbiAgICB0cmFjZUlkOiBzdHJpbmc7XG4gICAgcmVwb3J0OiBIYWxsdWNpbmF0aW9uUmVwb3J0O1xuICB9PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YShgL3F1YWxpdHkvaGFsbHVjaW5hdGlvbi1yZXBvcnQvJHt0cmFjZUlkfWAsIHtcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlIFJBRyBxdWFsaXR5IGZvciBwcm92aWRlZCBjb250ZW50IChhZC1ob2MgZXZhbHVhdGlvbilcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBxdWFsaXR5TWV0cmljcy5ldmFsdWF0ZVJhZyh7XG4gICAqICAgcXVlcnk6ICdXaGF0IGlzIHRoZSByZWZ1bmQgcG9saWN5PycsXG4gICAqICAgcmVzcG9uc2U6ICdZb3UgY2FuIGdldCBhIHJlZnVuZCB3aXRoaW4gMzAgZGF5cy4nLFxuICAgKiAgIHJldHJpZXZlZENvbnRleHRzOiBbXG4gICAqICAgICB7IGNvbnRlbnQ6ICdPdXIgcmVmdW5kIHBvbGljeSBhbGxvd3MgcmV0dXJucyB3aXRoaW4gMzAgZGF5cyBvZiBwdXJjaGFzZS4nIH0sXG4gICAqICAgXSxcbiAgICogfSk7XG4gICAqIGNvbnNvbGUubG9nKGBHcm91bmRlZG5lc3M6ICR7cmVzdWx0LmV2YWx1YXRpb24uZ3JvdW5kZWRuZXNzfWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGV2YWx1YXRlUmFnKGlucHV0OiB7XG4gICAgcXVlcnk6IHN0cmluZztcbiAgICByZXNwb25zZTogc3RyaW5nO1xuICAgIHJldHJpZXZlZENvbnRleHRzOiBSZXRyaWV2ZWRDb250ZXh0W107XG4gICAgZ3JvdW5kVHJ1dGhDb250ZXh0cz86IEdyb3VuZFRydXRoQ29udGV4dFtdO1xuICAgIGNpdGF0aW9ucz86IHN0cmluZ1tdO1xuICB9KTogUHJvbWlzZTx7XG4gICAgZXZhbHVhdGlvbjogUkFHRXZhbHVhdGlvbjtcbiAgICBldmlkZW5jZTogUkFHRXZpZGVuY2U7XG4gIH0+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhKCcvcXVhbGl0eS9ldmFsdWF0ZS1yYWcnLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IGlucHV0LFxuICAgICAgYXBpVmVyc2lvbjogJ3YxJyxcbiAgICB9KTtcbiAgfSxcblxuICAvKipcbiAgICogRGV0ZWN0IGhhbGx1Y2luYXRpb25zIGluIHByb3ZpZGVkIGNvbnRlbnQgKGFkLWhvYyBkZXRlY3Rpb24pXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgcXVhbGl0eU1ldHJpY3MuZGV0ZWN0SGFsbHVjaW5hdGlvbnMoe1xuICAgKiAgIHJlc3BvbnNlOiAnVGhlIHByb2R1Y3QgY29zdHMgJDk5IGFuZCBjb21lcyB3aXRoIGEgMi15ZWFyIHdhcnJhbnR5LicsXG4gICAqICAgY29udGV4dHM6IFtcbiAgICogICAgIHsgY29udGVudDogJ1RoZSBwcm9kdWN0IGNvc3RzICQ5OSB3aXRoIGEgMS15ZWFyIHdhcnJhbnR5LicgfSxcbiAgICogICBdLFxuICAgKiB9KTtcbiAgICogaWYgKHJlc3VsdC5yZXBvcnQuaGFzSGFsbHVjaW5hdGlvbnMpIHtcbiAgICogICBjb25zb2xlLmxvZygnRGV0ZWN0ZWQgaGFsbHVjaW5hdGlvbnM6JywgcmVzdWx0LnJlcG9ydC5pbnN0YW5jZXMpO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZGV0ZWN0SGFsbHVjaW5hdGlvbnMoaW5wdXQ6IHtcbiAgICByZXNwb25zZTogc3RyaW5nO1xuICAgIGNvbnRleHRzOiBBcnJheTx7IGNvbnRlbnQ6IHN0cmluZzsgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PjtcbiAgICBxdWVyeT86IHN0cmluZztcbiAgICBwcmV2aW91c1Jlc3BvbnNlcz86IHN0cmluZ1tdO1xuICB9KTogUHJvbWlzZTx7XG4gICAgcmVwb3J0OiBIYWxsdWNpbmF0aW9uUmVwb3J0O1xuICB9PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YSgnL3F1YWxpdHkvZGV0ZWN0LWhhbGx1Y2luYXRpb25zJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBpbnB1dCxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBncm91bmRlZG5lc3MgYW5hbHlzaXMgZm9yIGEgdHJhY2VcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBxdWFsaXR5TWV0cmljcy5nZXRHcm91bmRlZG5lc3MoJ3RyYWNlX2FiYzEyMycpO1xuICAgKiBjb25zb2xlLmxvZyhgR3JvdW5kZWRuZXNzIHNjb3JlOiAke3Jlc3VsdC5ncm91bmRlZG5lc3Muc2NvcmV9YCk7XG4gICAqIGNvbnNvbGUubG9nKGBHcm91bmRlZCBzcGFuczogJHtyZXN1bHQuc3VtbWFyeS5ncm91bmRlZFNwYW5zfWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldEdyb3VuZGVkbmVzcyh0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtcbiAgICB0cmFjZUlkOiBzdHJpbmc7XG4gICAgZ3JvdW5kZWRuZXNzOiBHcm91bmRlZG5lc3NSZXN1bHQ7XG4gICAgc3BhbnM6IHtcbiAgICAgIGdyb3VuZGVkOiBBcnJheTx7IHRleHQ6IHN0cmluZzsgY29uZmlkZW5jZTogbnVtYmVyOyBzb3VyY2VJbmRleDogbnVtYmVyIH0+O1xuICAgICAgdW5ncm91bmRlZDogQXJyYXk8eyB0ZXh0OiBzdHJpbmc7IGNvbmZpZGVuY2U6IG51bWJlciB9PjtcbiAgICB9O1xuICAgIHN1bW1hcnk6IHtcbiAgICAgIHRvdGFsU3BhbnM6IG51bWJlcjtcbiAgICAgIGdyb3VuZGVkU3BhbnM6IG51bWJlcjtcbiAgICAgIHVuZ3JvdW5kZWRTcGFuczogbnVtYmVyO1xuICAgICAgZ3JvdW5kZWRuZXNzUmF0aW86IG51bWJlcjtcbiAgICB9O1xuICB9PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YShgL3F1YWxpdHkvZ3JvdW5kZWRuZXNzLyR7dHJhY2VJZH1gLCB7XG4gICAgICBhcGlWZXJzaW9uOiAndjEnLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZSBtdWx0aXBsZSB0cmFjZXMgZm9yIHF1YWxpdHkgbWV0cmljcyBpbiBiYXRjaFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHF1YWxpdHlNZXRyaWNzLmV2YWx1YXRlQmF0Y2goe1xuICAgKiAgIHRyYWNlSWRzOiBbJ3RyYWNlXzEnLCAndHJhY2VfMicsICd0cmFjZV8zJ10sXG4gICAqIH0pO1xuICAgKiBjb25zb2xlLmxvZyhgQXZlcmFnZSBSQUcgc2NvcmU6ICR7cmVzdWx0LnN1bW1hcnkuYXZnUmFnU2NvcmV9YCk7XG4gICAqIGNvbnNvbGUubG9nKGBIYWxsdWNpbmF0aW9uIHJhdGU6ICR7cmVzdWx0LnN1bW1hcnkuaGFsbHVjaW5hdGlvblJhdGV9JWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGV2YWx1YXRlQmF0Y2gob3B0aW9uczoge1xuICAgIHRyYWNlSWRzOiBzdHJpbmdbXTtcbiAgICBpbmNsdWRlRGV0YWlscz86IGJvb2xlYW47XG4gIH0pOiBQcm9taXNlPHtcbiAgICBzdW1tYXJ5OiBCYXRjaEV2YWx1YXRpb25TdW1tYXJ5O1xuICAgIHJlc3VsdHM6IEJhdGNoRXZhbHVhdGlvblJlc3VsdFtdO1xuICB9PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YSgnL3F1YWxpdHkvZXZhbHVhdGUtYmF0Y2gnLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICBhcGlWZXJzaW9uOiAndjEnLFxuICAgIH0pO1xuICB9LFxufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIENoZWNrIGlmIGEgUkFHIGV2YWx1YXRpb24gcGFzc2VzIHF1YWxpdHkgdGhyZXNob2xkc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFzc2VzUXVhbGl0eVRocmVzaG9sZChcbiAgZXZhbHVhdGlvbjogUkFHRXZhbHVhdGlvbixcbiAgdGhyZXNob2xkczoge1xuICAgIG1pbkdyb3VuZGVkbmVzcz86IG51bWJlcjtcbiAgICBtaW5PdmVyYWxsU2NvcmU/OiBudW1iZXI7XG4gICAgbWluR3JhZGU/OiAnQScgfCAnQicgfCAnQycgfCAnRCc7XG4gIH0gPSB7fVxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgbWluR3JvdW5kZWRuZXNzID0gMC43LCBtaW5PdmVyYWxsU2NvcmUgPSA2MCwgbWluR3JhZGUgPSAnQycgfSA9IHRocmVzaG9sZHM7XG5cbiAgY29uc3QgZ3JhZGVPcmRlciA9IHsgQTogNCwgQjogMywgQzogMiwgRDogMSwgRjogMCB9O1xuICBjb25zdCBtZWV0c0dyb3VuZGVkbmVzcyA9IGV2YWx1YXRpb24uZ3JvdW5kZWRuZXNzID49IG1pbkdyb3VuZGVkbmVzcztcbiAgY29uc3QgbWVldHNTY29yZSA9IGV2YWx1YXRpb24ub3ZlcmFsbFNjb3JlID49IG1pbk92ZXJhbGxTY29yZTtcbiAgY29uc3QgbWVldHNHcmFkZSA9IGdyYWRlT3JkZXJbZXZhbHVhdGlvbi5ncmFkZV0gPj0gZ3JhZGVPcmRlclttaW5HcmFkZV07XG5cbiAgcmV0dXJuIG1lZXRzR3JvdW5kZWRuZXNzICYmIG1lZXRzU2NvcmUgJiYgbWVldHNHcmFkZTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBoYWxsdWNpbmF0aW9uIHJpc2sgaXMgYWNjZXB0YWJsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNIYWxsdWNpbmF0aW9uUmlza0FjY2VwdGFibGUoXG4gIHJlcG9ydDogSGFsbHVjaW5hdGlvblJlcG9ydCxcbiAgbWF4Umlza0xldmVsOiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnID0gJ21lZGl1bSdcbik6IGJvb2xlYW4ge1xuICBjb25zdCByaXNrT3JkZXIgPSB7IGxvdzogMCwgbWVkaXVtOiAxLCBoaWdoOiAyLCBjcml0aWNhbDogMyB9O1xuICByZXR1cm4gcmlza09yZGVyW3JlcG9ydC5yaXNrTGV2ZWxdIDw9IHJpc2tPcmRlclttYXhSaXNrTGV2ZWxdO1xufVxuXG4vKipcbiAqIEdldCBxdWFsaXR5IHJlY29tbWVuZGF0aW9ucyBiYXNlZCBvbiBldmFsdWF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRRdWFsaXR5UmVjb21tZW5kYXRpb25zKFxuICByYWdFdmFsOiBSQUdFdmFsdWF0aW9uLFxuICBoYWxsdWNpbmF0aW9uUmVwb3J0PzogSGFsbHVjaW5hdGlvblJlcG9ydFxuKTogc3RyaW5nW10ge1xuICBjb25zdCByZWNvbW1lbmRhdGlvbnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKHJhZ0V2YWwuZ3JvdW5kZWRuZXNzIDwgMC43KSB7XG4gICAgcmVjb21tZW5kYXRpb25zLnB1c2goJ0ltcHJvdmUgZ3JvdW5kaW5nIGJ5IGluY3JlYXNpbmcgY29udGV4dCByZWxldmFuY2UnKTtcbiAgfVxuXG4gIGlmIChyYWdFdmFsLmNvbnRleHRSZWxldmFuY2UgPCAwLjYpIHtcbiAgICByZWNvbW1lbmRhdGlvbnMucHVzaCgnVHVuZSByZXRyaWV2YWwgdG8gcmV0dXJuIG1vcmUgcmVsZXZhbnQgY29udGV4dHMnKTtcbiAgfVxuXG4gIGlmIChyYWdFdmFsLmNpdGF0aW9uQWNjdXJhY3kgPCAwLjgpIHtcbiAgICByZWNvbW1lbmRhdGlvbnMucHVzaCgnSW1wcm92ZSBjaXRhdGlvbiBhY2N1cmFjeSBpbiByZXNwb25zZXMnKTtcbiAgfVxuXG4gIGlmIChoYWxsdWNpbmF0aW9uUmVwb3J0Py5oYXNIYWxsdWNpbmF0aW9ucykge1xuICAgIHJlY29tbWVuZGF0aW9ucy5wdXNoKCdBZGQgZmFjdC1jaGVja2luZyBsYXllciB0byByZWR1Y2UgaGFsbHVjaW5hdGlvbnMnKTtcbiAgfVxuXG4gIGlmIChyZWNvbW1lbmRhdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmVjb21tZW5kYXRpb25zLnB1c2goJ1F1YWxpdHkgbWV0cmljcyBhcmUgd2l0aGluIGFjY2VwdGFibGUgcmFuZ2VzJyk7XG4gIH1cblxuICByZXR1cm4gcmVjb21tZW5kYXRpb25zO1xufVxuXG4vKipcbiAqIEZvcm1hdCBxdWFsaXR5IHNjb3JlIGZvciBkaXNwbGF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRRdWFsaXR5U2NvcmUoc2NvcmU6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBgJHtNYXRoLnJvdW5kKHNjb3JlICogMTAwKX0lYDtcbn1cblxuLyoqXG4gKiBHZXQgY29sb3IgaW5kaWNhdG9yIGZvciBncmFkZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0R3JhZGVDb2xvcihcbiAgZ3JhZGU6ICdBJyB8ICdCJyB8ICdDJyB8ICdEJyB8ICdGJ1xuKTogJ2dyZWVuJyB8ICdibHVlJyB8ICd5ZWxsb3cnIHwgJ29yYW5nZScgfCAncmVkJyB7XG4gIGNvbnN0IGNvbG9ycyA9IHtcbiAgICBBOiAnZ3JlZW4nIGFzIGNvbnN0LFxuICAgIEI6ICdibHVlJyBhcyBjb25zdCxcbiAgICBDOiAneWVsbG93JyBhcyBjb25zdCxcbiAgICBEOiAnb3JhbmdlJyBhcyBjb25zdCxcbiAgICBGOiAncmVkJyBhcyBjb25zdCxcbiAgfTtcbiAgcmV0dXJuIGNvbG9yc1tncmFkZV07XG59XG4iXX0=
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThinkHive SDK v3.1 - ROI Analytics API
|
|
3
|
+
*
|
|
4
|
+
* Business ROI & Metrics Engine for calculating financial impact
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Industry-specific ROI configuration
|
|
8
|
+
*/
|
|
9
|
+
export interface IndustryConfig {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
avgTransactionValue: number;
|
|
13
|
+
avgCustomerLTV: number;
|
|
14
|
+
avgSupportCost: number;
|
|
15
|
+
avgEscalationCost: number;
|
|
16
|
+
avgResolutionTime: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Custom industry config input
|
|
20
|
+
*/
|
|
21
|
+
export interface CustomIndustryConfig {
|
|
22
|
+
industry?: string;
|
|
23
|
+
avgTransactionValue?: number;
|
|
24
|
+
avgCustomerLTV?: number;
|
|
25
|
+
avgSupportCost?: number;
|
|
26
|
+
avgEscalationCost?: number;
|
|
27
|
+
churnImpactMultiplier?: number;
|
|
28
|
+
avgResolutionTime?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* ROI metrics summary
|
|
32
|
+
*/
|
|
33
|
+
export interface ROIMetrics {
|
|
34
|
+
roiCategory: string;
|
|
35
|
+
totalFinancialImpact: number;
|
|
36
|
+
revenueProtected: number;
|
|
37
|
+
costSavings: number;
|
|
38
|
+
efficiencyGain: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Business impact analysis result
|
|
42
|
+
*/
|
|
43
|
+
export interface BusinessImpact {
|
|
44
|
+
impactScore: number;
|
|
45
|
+
revenueRisk: number;
|
|
46
|
+
brandRisk: number;
|
|
47
|
+
complianceRisk: number;
|
|
48
|
+
operationalImpact: number;
|
|
49
|
+
customerSatisfaction: number;
|
|
50
|
+
recommendations: string[];
|
|
51
|
+
roi: ROIMetrics;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* ROI summary for a date range
|
|
55
|
+
*/
|
|
56
|
+
export interface ROISummary {
|
|
57
|
+
dateRange: {
|
|
58
|
+
start: string;
|
|
59
|
+
end: string;
|
|
60
|
+
};
|
|
61
|
+
traceCount: number;
|
|
62
|
+
successfulInteractions: number;
|
|
63
|
+
failedInteractions: number;
|
|
64
|
+
successRate: number;
|
|
65
|
+
roi: ROIMetrics;
|
|
66
|
+
revenueProtected: number;
|
|
67
|
+
estimatedSavings: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Daily trend data point
|
|
71
|
+
*/
|
|
72
|
+
export interface TrendDataPoint {
|
|
73
|
+
date: string;
|
|
74
|
+
traceCount: number;
|
|
75
|
+
successCount: number;
|
|
76
|
+
failureCount: number;
|
|
77
|
+
successRate: number;
|
|
78
|
+
avgImpactScore: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Correlation finding
|
|
82
|
+
*/
|
|
83
|
+
export interface Correlation {
|
|
84
|
+
type: string;
|
|
85
|
+
strength: string;
|
|
86
|
+
coefficient: number;
|
|
87
|
+
confidence: number;
|
|
88
|
+
description: string;
|
|
89
|
+
insight: string;
|
|
90
|
+
recommendation: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Pattern cluster
|
|
94
|
+
*/
|
|
95
|
+
export interface PatternCluster {
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
matchCount: number;
|
|
99
|
+
avgImpactScore: number;
|
|
100
|
+
avgChurnRisk: number;
|
|
101
|
+
trend: string;
|
|
102
|
+
examples: string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Correlation analysis result
|
|
106
|
+
*/
|
|
107
|
+
export interface CorrelationAnalysis {
|
|
108
|
+
analysisId: string;
|
|
109
|
+
analyzedAt: string;
|
|
110
|
+
traceCount: number;
|
|
111
|
+
timeRange: {
|
|
112
|
+
start: string;
|
|
113
|
+
end: string;
|
|
114
|
+
};
|
|
115
|
+
overallHealthScore: number;
|
|
116
|
+
topInsights: string[];
|
|
117
|
+
recommendations: string[];
|
|
118
|
+
correlations: Correlation[];
|
|
119
|
+
patternClusters: PatternCluster[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* ROI Analytics API client for business impact analysis
|
|
123
|
+
*/
|
|
124
|
+
export declare const roiAnalytics: {
|
|
125
|
+
/**
|
|
126
|
+
* Get aggregated ROI summary for traces in date range
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const summary = await roiAnalytics.summary({
|
|
131
|
+
* startDate: '2024-01-01',
|
|
132
|
+
* endDate: '2024-01-31',
|
|
133
|
+
* });
|
|
134
|
+
* console.log(`Revenue protected: $${summary.revenueProtected}`);
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
summary(options?: {
|
|
138
|
+
startDate?: string | Date;
|
|
139
|
+
endDate?: string | Date;
|
|
140
|
+
agentId?: string;
|
|
141
|
+
}): Promise<ROISummary>;
|
|
142
|
+
/**
|
|
143
|
+
* Get ROI metrics for a specific agent
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const agentROI = await roiAnalytics.byAgent('agent_123', {
|
|
148
|
+
* startDate: '2024-01-01',
|
|
149
|
+
* });
|
|
150
|
+
* console.log(`Agent: ${agentROI.agent.name}`);
|
|
151
|
+
* console.log(`ROI: ${agentROI.roi.totalFinancialImpact}`);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
byAgent(agentId: string, options?: {
|
|
155
|
+
startDate?: string | Date;
|
|
156
|
+
endDate?: string | Date;
|
|
157
|
+
}): Promise<{
|
|
158
|
+
agent: {
|
|
159
|
+
id: string;
|
|
160
|
+
name: string;
|
|
161
|
+
industry: string;
|
|
162
|
+
};
|
|
163
|
+
industryConfig: Partial<IndustryConfig>;
|
|
164
|
+
roi: ROIMetrics;
|
|
165
|
+
recentImpacts: Array<{
|
|
166
|
+
impactScore: number;
|
|
167
|
+
revenueRisk: number;
|
|
168
|
+
roiCategory: string;
|
|
169
|
+
totalFinancialImpact: number;
|
|
170
|
+
}>;
|
|
171
|
+
}>;
|
|
172
|
+
/**
|
|
173
|
+
* Get ROI trends over time
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const trends = await roiAnalytics.trends({
|
|
178
|
+
* startDate: '2024-01-01',
|
|
179
|
+
* endDate: '2024-01-31',
|
|
180
|
+
* });
|
|
181
|
+
* for (const day of trends) {
|
|
182
|
+
* console.log(`${day.date}: ${day.successRate}% success`);
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
trends(options?: {
|
|
187
|
+
startDate?: string | Date;
|
|
188
|
+
endDate?: string | Date;
|
|
189
|
+
agentId?: string;
|
|
190
|
+
}): Promise<TrendDataPoint[]>;
|
|
191
|
+
/**
|
|
192
|
+
* Calculate ROI for a trace or provided message data
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* // Calculate for existing trace
|
|
197
|
+
* const impact = await roiAnalytics.calculate({
|
|
198
|
+
* traceId: 'trace_abc123',
|
|
199
|
+
* });
|
|
200
|
+
*
|
|
201
|
+
* // Calculate for new data with custom config
|
|
202
|
+
* const impact = await roiAnalytics.calculate({
|
|
203
|
+
* userMessage: 'Help me cancel my subscription',
|
|
204
|
+
* agentResponse: 'I can help with that...',
|
|
205
|
+
* industryConfig: { industry: 'saas', avgCustomerLTV: 10000 },
|
|
206
|
+
* });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
calculate(options: {
|
|
210
|
+
traceId?: string;
|
|
211
|
+
userMessage?: string;
|
|
212
|
+
agentResponse?: string;
|
|
213
|
+
industryConfig?: CustomIndustryConfig;
|
|
214
|
+
}): Promise<BusinessImpact>;
|
|
215
|
+
/**
|
|
216
|
+
* Get available industry configurations
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* const industries = await roiAnalytics.industries();
|
|
221
|
+
* for (const config of industries) {
|
|
222
|
+
* console.log(`${config.name}: $${config.avgCustomerLTV} LTV`);
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
industries(): Promise<IndustryConfig[]>;
|
|
227
|
+
/**
|
|
228
|
+
* Get correlation analysis for traces
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const analysis = await roiAnalytics.correlations({
|
|
233
|
+
* startDate: '2024-01-01',
|
|
234
|
+
* agentId: 'agent_123',
|
|
235
|
+
* });
|
|
236
|
+
* console.log(`Health score: ${analysis.overallHealthScore}`);
|
|
237
|
+
* for (const insight of analysis.topInsights) {
|
|
238
|
+
* console.log(`- ${insight}`);
|
|
239
|
+
* }
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
correlations(options?: {
|
|
243
|
+
startDate?: string | Date;
|
|
244
|
+
endDate?: string | Date;
|
|
245
|
+
agentId?: string;
|
|
246
|
+
}): Promise<CorrelationAnalysis>;
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Calculate estimated revenue at risk
|
|
250
|
+
*/
|
|
251
|
+
export declare function calculateRevenueAtRisk(failureRate: number, avgTransactionValue: number, totalInteractions: number): number;
|
|
252
|
+
/**
|
|
253
|
+
* Calculate estimated savings from automation
|
|
254
|
+
*/
|
|
255
|
+
export declare function calculateAutomationSavings(successfulInteractions: number, avgSupportCost: number): number;
|
|
256
|
+
/**
|
|
257
|
+
* Format currency for display
|
|
258
|
+
*/
|
|
259
|
+
export declare function formatCurrency(amount: number, currency?: string): string;
|
|
260
|
+
/**
|
|
261
|
+
* Get ROI quality label
|
|
262
|
+
*/
|
|
263
|
+
export declare function getROIQuality(totalFinancialImpact: number): 'excellent' | 'good' | 'moderate' | 'poor';
|