@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.
@@ -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';