@thinkhive/sdk 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,204 @@
1
+ /**
2
+ * ThinkHive SDK v3.0 - Transcript Patterns API
3
+ *
4
+ * API for transcript pattern detection and analysis
5
+ */
6
+ export type PatternCategory = 'frustration' | 'confusion' | 'success' | 'failure' | 'escalation' | 'pii_exposure' | 'hallucination' | 'custom';
7
+ export type PatternOutcome = 'success' | 'failure' | 'escalation' | 'neutral';
8
+ export type PatternSeverity = 'info' | 'warning' | 'critical';
9
+ export type DetectionType = 'sequence' | 'keywords' | 'regex';
10
+ export interface PatternMatch {
11
+ patternId: string;
12
+ patternName: string;
13
+ category: PatternCategory;
14
+ matchedText?: string;
15
+ position?: {
16
+ start: number;
17
+ end: number;
18
+ };
19
+ confidence: number;
20
+ severity: PatternSeverity;
21
+ }
22
+ export interface PatternInsight {
23
+ type: string;
24
+ message: string;
25
+ severity: PatternSeverity;
26
+ recommendation?: string;
27
+ }
28
+ export interface AnalysisResult {
29
+ traceId: string;
30
+ sessionId?: string;
31
+ patternsMatched: number;
32
+ riskScore: number;
33
+ predictedOutcome?: PatternOutcome;
34
+ predictionConfidence?: number;
35
+ matches: PatternMatch[];
36
+ insights: PatternInsight[];
37
+ sentimentScores?: {
38
+ overall: number;
39
+ byTurn?: Array<{
40
+ turn: number;
41
+ sentiment: number;
42
+ confidence: number;
43
+ }>;
44
+ };
45
+ }
46
+ export interface BulkAnalysisResult {
47
+ results: Array<AnalysisResult & {
48
+ error?: string;
49
+ }>;
50
+ summary: {
51
+ tracesAnalyzed: number;
52
+ totalMatches: number;
53
+ tracesWithMatches: number;
54
+ };
55
+ }
56
+ export interface PatternCategoryInfo {
57
+ id: PatternCategory;
58
+ name: string;
59
+ description: string;
60
+ indicators: string[];
61
+ }
62
+ export interface BuiltInPattern {
63
+ id: string;
64
+ name: string;
65
+ category: PatternCategory;
66
+ detectionType: DetectionType;
67
+ description: string;
68
+ }
69
+ /**
70
+ * Transcript Patterns API client for pattern detection and analysis
71
+ */
72
+ export declare const transcriptPatterns: {
73
+ /**
74
+ * Analyze a trace for patterns
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const result = await transcriptPatterns.analyze('trace_123');
79
+ * console.log(`Found ${result.patternsMatched} patterns`);
80
+ * console.log(`Risk score: ${result.riskScore}`);
81
+ * ```
82
+ */
83
+ analyze(traceId: string): Promise<AnalysisResult>;
84
+ /**
85
+ * Analyze multiple traces for patterns
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const { results, summary } = await transcriptPatterns.bulkAnalyze([
90
+ * 'trace_1', 'trace_2', 'trace_3'
91
+ * ]);
92
+ * console.log(`${summary.tracesWithMatches} traces have patterns`);
93
+ * ```
94
+ */
95
+ bulkAnalyze(traceIds: string[]): Promise<BulkAnalysisResult>;
96
+ /**
97
+ * Get available pattern categories with descriptions
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const categories = await transcriptPatterns.getCategories();
102
+ * for (const category of categories) {
103
+ * console.log(`${category.name}: ${category.description}`);
104
+ * }
105
+ * ```
106
+ */
107
+ getCategories(): Promise<PatternCategoryInfo[]>;
108
+ /**
109
+ * Get built-in patterns
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const patterns = await transcriptPatterns.getBuiltInPatterns();
114
+ * const frustrationPatterns = patterns.filter(p => p.category === 'frustration');
115
+ * ```
116
+ */
117
+ getBuiltInPatterns(): Promise<BuiltInPattern[]>;
118
+ };
119
+ /**
120
+ * Check if analysis result indicates high risk
121
+ *
122
+ * @param result - Analysis result to check
123
+ * @param threshold - Risk score threshold (default 70)
124
+ * @returns Whether the result indicates high risk
125
+ */
126
+ export declare function isHighRisk(result: AnalysisResult, threshold?: number): boolean;
127
+ /**
128
+ * Get matches by category
129
+ *
130
+ * @param result - Analysis result
131
+ * @param category - Pattern category to filter by
132
+ * @returns Filtered pattern matches
133
+ */
134
+ export declare function getMatchesByCategory(result: AnalysisResult, category: PatternCategory): PatternMatch[];
135
+ /**
136
+ * Get critical insights from analysis
137
+ *
138
+ * @param result - Analysis result
139
+ * @returns Critical severity insights
140
+ */
141
+ export declare function getCriticalInsights(result: AnalysisResult): PatternInsight[];
142
+ /**
143
+ * Check if analysis detected PII
144
+ *
145
+ * @param result - Analysis result
146
+ * @returns Whether PII was detected
147
+ */
148
+ export declare function hasPiiExposure(result: AnalysisResult): boolean;
149
+ /**
150
+ * Check if analysis detected frustration
151
+ *
152
+ * @param result - Analysis result
153
+ * @returns Whether frustration was detected
154
+ */
155
+ export declare function hasFrustrationSignals(result: AnalysisResult): boolean;
156
+ /**
157
+ * Check if analysis detected escalation request
158
+ *
159
+ * @param result - Analysis result
160
+ * @returns Whether escalation was requested
161
+ */
162
+ export declare function hasEscalationRequest(result: AnalysisResult): boolean;
163
+ /**
164
+ * Calculate category distribution
165
+ *
166
+ * @param result - Analysis result
167
+ * @returns Object with counts per category
168
+ */
169
+ export declare function getCategoryDistribution(result: AnalysisResult): Record<PatternCategory, number>;
170
+ /**
171
+ * Get actionable recommendations from insights
172
+ *
173
+ * @param result - Analysis result
174
+ * @returns Array of recommendation strings
175
+ */
176
+ export declare function getRecommendations(result: AnalysisResult): string[];
177
+ /**
178
+ * Calculate overall sentiment from analysis
179
+ *
180
+ * @param result - Analysis result
181
+ * @returns Sentiment score (-1 to 1) or null if not available
182
+ */
183
+ export declare function getOverallSentiment(result: AnalysisResult): number | null;
184
+ /**
185
+ * Determine if conversation needs attention based on patterns
186
+ *
187
+ * @param result - Analysis result
188
+ * @returns Whether the conversation needs attention
189
+ */
190
+ export declare function needsAttention(result: AnalysisResult): boolean;
191
+ /**
192
+ * Get severity level as numeric value
193
+ *
194
+ * @param severity - Pattern severity
195
+ * @returns Numeric severity (1-3)
196
+ */
197
+ export declare function getSeverityLevel(severity: PatternSeverity): number;
198
+ /**
199
+ * Sort matches by severity (critical first)
200
+ *
201
+ * @param matches - Pattern matches to sort
202
+ * @returns Sorted matches
203
+ */
204
+ export declare function sortMatchesBySeverity(matches: PatternMatch[]): PatternMatch[];
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ /**
3
+ * ThinkHive SDK v3.0 - Transcript Patterns API
4
+ *
5
+ * API for transcript pattern detection and analysis
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.transcriptPatterns = void 0;
9
+ exports.isHighRisk = isHighRisk;
10
+ exports.getMatchesByCategory = getMatchesByCategory;
11
+ exports.getCriticalInsights = getCriticalInsights;
12
+ exports.hasPiiExposure = hasPiiExposure;
13
+ exports.hasFrustrationSignals = hasFrustrationSignals;
14
+ exports.hasEscalationRequest = hasEscalationRequest;
15
+ exports.getCategoryDistribution = getCategoryDistribution;
16
+ exports.getRecommendations = getRecommendations;
17
+ exports.getOverallSentiment = getOverallSentiment;
18
+ exports.needsAttention = needsAttention;
19
+ exports.getSeverityLevel = getSeverityLevel;
20
+ exports.sortMatchesBySeverity = sortMatchesBySeverity;
21
+ const client_1 = require("../core/client");
22
+ // ============================================================================
23
+ // TRANSCRIPT PATTERNS API CLIENT
24
+ // ============================================================================
25
+ /**
26
+ * Transcript Patterns API client for pattern detection and analysis
27
+ */
28
+ exports.transcriptPatterns = {
29
+ /**
30
+ * Analyze a trace for patterns
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const result = await transcriptPatterns.analyze('trace_123');
35
+ * console.log(`Found ${result.patternsMatched} patterns`);
36
+ * console.log(`Risk score: ${result.riskScore}`);
37
+ * ```
38
+ */
39
+ async analyze(traceId) {
40
+ return (0, client_1.apiRequestWithData)('/transcript-patterns/analyze', {
41
+ method: 'POST',
42
+ body: { traceId },
43
+ apiVersion: 'v1',
44
+ });
45
+ },
46
+ /**
47
+ * Analyze multiple traces for patterns
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const { results, summary } = await transcriptPatterns.bulkAnalyze([
52
+ * 'trace_1', 'trace_2', 'trace_3'
53
+ * ]);
54
+ * console.log(`${summary.tracesWithMatches} traces have patterns`);
55
+ * ```
56
+ */
57
+ async bulkAnalyze(traceIds) {
58
+ return (0, client_1.apiRequestWithData)('/transcript-patterns/bulk-analyze', {
59
+ method: 'POST',
60
+ body: { traceIds },
61
+ apiVersion: 'v1',
62
+ });
63
+ },
64
+ /**
65
+ * Get available pattern categories with descriptions
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const categories = await transcriptPatterns.getCategories();
70
+ * for (const category of categories) {
71
+ * console.log(`${category.name}: ${category.description}`);
72
+ * }
73
+ * ```
74
+ */
75
+ async getCategories() {
76
+ return (0, client_1.apiRequestWithData)('/transcript-patterns/categories', { apiVersion: 'v1' });
77
+ },
78
+ /**
79
+ * Get built-in patterns
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const patterns = await transcriptPatterns.getBuiltInPatterns();
84
+ * const frustrationPatterns = patterns.filter(p => p.category === 'frustration');
85
+ * ```
86
+ */
87
+ async getBuiltInPatterns() {
88
+ return (0, client_1.apiRequestWithData)('/transcript-patterns/built-in', { apiVersion: 'v1' });
89
+ },
90
+ };
91
+ // ============================================================================
92
+ // HELPER FUNCTIONS
93
+ // ============================================================================
94
+ /**
95
+ * Check if analysis result indicates high risk
96
+ *
97
+ * @param result - Analysis result to check
98
+ * @param threshold - Risk score threshold (default 70)
99
+ * @returns Whether the result indicates high risk
100
+ */
101
+ function isHighRisk(result, threshold = 70) {
102
+ return result.riskScore >= threshold;
103
+ }
104
+ /**
105
+ * Get matches by category
106
+ *
107
+ * @param result - Analysis result
108
+ * @param category - Pattern category to filter by
109
+ * @returns Filtered pattern matches
110
+ */
111
+ function getMatchesByCategory(result, category) {
112
+ return result.matches.filter(m => m.category === category);
113
+ }
114
+ /**
115
+ * Get critical insights from analysis
116
+ *
117
+ * @param result - Analysis result
118
+ * @returns Critical severity insights
119
+ */
120
+ function getCriticalInsights(result) {
121
+ return result.insights.filter(i => i.severity === 'critical');
122
+ }
123
+ /**
124
+ * Check if analysis detected PII
125
+ *
126
+ * @param result - Analysis result
127
+ * @returns Whether PII was detected
128
+ */
129
+ function hasPiiExposure(result) {
130
+ return result.matches.some(m => m.category === 'pii_exposure');
131
+ }
132
+ /**
133
+ * Check if analysis detected frustration
134
+ *
135
+ * @param result - Analysis result
136
+ * @returns Whether frustration was detected
137
+ */
138
+ function hasFrustrationSignals(result) {
139
+ return result.matches.some(m => m.category === 'frustration');
140
+ }
141
+ /**
142
+ * Check if analysis detected escalation request
143
+ *
144
+ * @param result - Analysis result
145
+ * @returns Whether escalation was requested
146
+ */
147
+ function hasEscalationRequest(result) {
148
+ return result.matches.some(m => m.category === 'escalation');
149
+ }
150
+ /**
151
+ * Calculate category distribution
152
+ *
153
+ * @param result - Analysis result
154
+ * @returns Object with counts per category
155
+ */
156
+ function getCategoryDistribution(result) {
157
+ const distribution = {
158
+ frustration: 0,
159
+ confusion: 0,
160
+ success: 0,
161
+ failure: 0,
162
+ escalation: 0,
163
+ pii_exposure: 0,
164
+ hallucination: 0,
165
+ custom: 0,
166
+ };
167
+ for (const match of result.matches) {
168
+ distribution[match.category]++;
169
+ }
170
+ return distribution;
171
+ }
172
+ /**
173
+ * Get actionable recommendations from insights
174
+ *
175
+ * @param result - Analysis result
176
+ * @returns Array of recommendation strings
177
+ */
178
+ function getRecommendations(result) {
179
+ return result.insights
180
+ .filter(i => i.recommendation)
181
+ .map(i => i.recommendation);
182
+ }
183
+ /**
184
+ * Calculate overall sentiment from analysis
185
+ *
186
+ * @param result - Analysis result
187
+ * @returns Sentiment score (-1 to 1) or null if not available
188
+ */
189
+ function getOverallSentiment(result) {
190
+ return result.sentimentScores?.overall ?? null;
191
+ }
192
+ /**
193
+ * Determine if conversation needs attention based on patterns
194
+ *
195
+ * @param result - Analysis result
196
+ * @returns Whether the conversation needs attention
197
+ */
198
+ function needsAttention(result) {
199
+ return (result.riskScore >= 50 ||
200
+ hasPiiExposure(result) ||
201
+ hasEscalationRequest(result) ||
202
+ result.insights.some(i => i.severity === 'critical'));
203
+ }
204
+ /**
205
+ * Get severity level as numeric value
206
+ *
207
+ * @param severity - Pattern severity
208
+ * @returns Numeric severity (1-3)
209
+ */
210
+ function getSeverityLevel(severity) {
211
+ switch (severity) {
212
+ case 'info': return 1;
213
+ case 'warning': return 2;
214
+ case 'critical': return 3;
215
+ default: return 0;
216
+ }
217
+ }
218
+ /**
219
+ * Sort matches by severity (critical first)
220
+ *
221
+ * @param matches - Pattern matches to sort
222
+ * @returns Sorted matches
223
+ */
224
+ function sortMatchesBySeverity(matches) {
225
+ return [...matches].sort((a, b) => getSeverityLevel(b.severity) - getSeverityLevel(a.severity));
226
+ }
227
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNjcmlwdC1wYXR0ZXJucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvdHJhbnNjcmlwdC1wYXR0ZXJucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7R0FJRzs7O0FBeUtILGdDQUVDO0FBU0Qsb0RBS0M7QUFRRCxrREFFQztBQVFELHdDQUVDO0FBUUQsc0RBRUM7QUFRRCxvREFFQztBQVFELDBEQWlCQztBQVFELGdEQUlDO0FBUUQsa0RBRUM7QUFRRCx3Q0FPQztBQVFELDRDQU9DO0FBUUQsc0RBRUM7QUF0VEQsMkNBQW9EO0FBNEVwRCwrRUFBK0U7QUFDL0UsaUNBQWlDO0FBQ2pDLCtFQUErRTtBQUUvRTs7R0FFRztBQUNVLFFBQUEsa0JBQWtCLEdBQUc7SUFDaEM7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFlO1FBQzNCLE9BQU8sSUFBQSwyQkFBa0IsRUFBaUIsOEJBQThCLEVBQUU7WUFDeEUsTUFBTSxFQUFFLE1BQU07WUFDZCxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUU7WUFDakIsVUFBVSxFQUFFLElBQUk7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLFFBQWtCO1FBQ2xDLE9BQU8sSUFBQSwyQkFBa0IsRUFBcUIsbUNBQW1DLEVBQUU7WUFDakYsTUFBTSxFQUFFLE1BQU07WUFDZCxJQUFJLEVBQUUsRUFBRSxRQUFRLEVBQUU7WUFDbEIsVUFBVSxFQUFFLElBQUk7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxLQUFLLENBQUMsYUFBYTtRQUNqQixPQUFPLElBQUEsMkJBQWtCLEVBQ3ZCLGlDQUFpQyxFQUNqQyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FDckIsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtB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QUFDLE1BQU0sQ0FBQztRQUN0QixvQkFBb0IsQ0FBQyxNQUFNLENBQUM7UUFDNUIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxLQUFLLFVBQVUsQ0FBQyxDQUNyRCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQUMsUUFBeUI7SUFDeEQsUUFBUSxRQUFRLEVBQUUsQ0FBQztRQUNqQixLQUFLLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RCLEtBQUssU0FBUyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDekIsS0FBSyxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQixPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwQixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQUMsT0FBdUI7SUFDM0QsT0FBTyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ2xHLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaW5rSGl2ZSBTREsgdjMuMCAtIFRyYW5zY3JpcHQgUGF0dGVybnMgQVBJXG4gKlxuICogQVBJIGZvciB0cmFuc2NyaXB0IHBhdHRlcm4gZGV0ZWN0aW9uIGFuZCBhbmFseXNpc1xuICovXG5cbmltcG9ydCB7IGFwaVJlcXVlc3RXaXRoRGF0YSB9IGZyb20gJy4uL2NvcmUvY2xpZW50JztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVFlQRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IHR5cGUgUGF0dGVybkNhdGVnb3J5ID1cbiAgfCAnZnJ1c3RyYXRpb24nXG4gIHwgJ2NvbmZ1c2lvbidcbiAgfCAnc3VjY2VzcydcbiAgfCAnZmFpbHVyZSdcbiAgfCAnZXNjYWxhdGlvbidcbiAgfCAncGlpX2V4cG9zdXJlJ1xuICB8ICdoYWxsdWNpbmF0aW9uJ1xuICB8ICdjdXN0b20nO1xuXG5leHBvcnQgdHlwZSBQYXR0ZXJuT3V0Y29tZSA9ICdzdWNjZXNzJyB8ICdmYWlsdXJlJyB8ICdlc2NhbGF0aW9uJyB8ICduZXV0cmFsJztcbmV4cG9ydCB0eXBlIFBhdHRlcm5TZXZlcml0eSA9ICdpbmZvJyB8ICd3YXJuaW5nJyB8ICdjcml0aWNhbCc7XG5leHBvcnQgdHlwZSBEZXRlY3Rpb25UeXBlID0gJ3NlcXVlbmNlJyB8ICdrZXl3b3JkcycgfCAncmVnZXgnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhdHRlcm5NYXRjaCB7XG4gIHBhdHRlcm5JZDogc3RyaW5nO1xuICBwYXR0ZXJuTmFtZTogc3RyaW5nO1xuICBjYXRlZ29yeTogUGF0dGVybkNhdGVnb3J5O1xuICBtYXRjaGVkVGV4dD86IHN0cmluZztcbiAgcG9zaXRpb24/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH07XG4gIGNvbmZpZGVuY2U6IG51bWJlcjtcbiAgc2V2ZXJpdHk6IFBhdHRlcm5TZXZlcml0eTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXR0ZXJuSW5zaWdodCB7XG4gIHR5cGU6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBzZXZlcml0eTogUGF0dGVyblNldmVyaXR5O1xuICByZWNvbW1lbmRhdGlvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBbmFseXNpc1Jlc3VsdCB7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgc2Vzc2lvbklkPzogc3RyaW5nO1xuICBwYXR0ZXJuc01hdGNoZWQ6IG51bWJlcjtcbiAgcmlza1Njb3JlOiBudW1iZXI7XG4gIHByZWRpY3RlZE91dGNvbWU/OiBQYXR0ZXJuT3V0Y29tZTtcbiAgcHJlZGljdGlvbkNvbmZpZGVuY2U/OiBudW1iZXI7XG4gIG1hdGNoZXM6IFBhdHRlcm5NYXRjaFtdO1xuICBpbnNpZ2h0czogUGF0dGVybkluc2lnaHRbXTtcbiAgc2VudGltZW50U2NvcmVzPzoge1xuICAgIG92ZXJhbGw6IG51bWJlcjtcbiAgICBieVR1cm4/OiBBcnJheTx7IHR1cm46IG51bWJlcjsgc2VudGltZW50OiBudW1iZXI7IGNvbmZpZGVuY2U6IG51bWJlciB9PjtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCdWxrQW5hbHlzaXNSZXN1bHQge1xuICByZXN1bHRzOiBBcnJheTxBbmFseXNpc1Jlc3VsdCAmIHsgZXJyb3I/OiBzdHJpbmcgfT47XG4gIHN1bW1hcnk6IHtcbiAgICB0cmFjZXNBbmFseXplZDogbnVtYmVyO1xuICAgIHRvdGFsTWF0Y2hlczogbnVtYmVyO1xuICAgIHRyYWNlc1dpdGhNYXRjaGVzOiBudW1iZXI7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGF0dGVybkNhdGVnb3J5SW5mbyB7XG4gIGlkOiBQYXR0ZXJuQ2F0ZWdvcnk7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgaW5kaWNhdG9yczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbHRJblBhdHRlcm4ge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBQYXR0ZXJuQ2F0ZWdvcnk7XG4gIGRldGVjdGlvblR5cGU6IERldGVjdGlvblR5cGU7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRSQU5TQ1JJUFQgUEFUVEVSTlMgQVBJIENMSUVOVFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFRyYW5zY3JpcHQgUGF0dGVybnMgQVBJIGNsaWVudCBmb3IgcGF0dGVybiBkZXRlY3Rpb24gYW5kIGFuYWx5c2lzXG4gKi9cbmV4cG9ydCBjb25zdCB0cmFuc2NyaXB0UGF0dGVybnMgPSB7XG4gIC8qKlxuICAgKiBBbmFseXplIGEgdHJhY2UgZm9yIHBhdHRlcm5zXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgdHJhbnNjcmlwdFBhdHRlcm5zLmFuYWx5emUoJ3RyYWNlXzEyMycpO1xuICAgKiBjb25zb2xlLmxvZyhgRm91bmQgJHtyZXN1bHQucGF0dGVybnNNYXRjaGVkfSBwYXR0ZXJuc2ApO1xuICAgKiBjb25zb2xlLmxvZyhgUmlzayBzY29yZTogJHtyZXN1bHQucmlza1Njb3JlfWApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGFuYWx5emUodHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTxBbmFseXNpc1Jlc3VsdD4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8QW5hbHlzaXNSZXN1bHQ+KCcvdHJhbnNjcmlwdC1wYXR0ZXJucy9hbmFseXplJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiB7IHRyYWNlSWQgfSxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEFuYWx5emUgbXVsdGlwbGUgdHJhY2VzIGZvciBwYXR0ZXJuc1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHsgcmVzdWx0cywgc3VtbWFyeSB9ID0gYXdhaXQgdHJhbnNjcmlwdFBhdHRlcm5zLmJ1bGtBbmFseXplKFtcbiAgICogICAndHJhY2VfMScsICd0cmFjZV8yJywgJ3RyYWNlXzMnXG4gICAqIF0pO1xuICAgKiBjb25zb2xlLmxvZyhgJHtzdW1tYXJ5LnRyYWNlc1dpdGhNYXRjaGVzfSB0cmFjZXMgaGF2ZSBwYXR0ZXJuc2ApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGJ1bGtBbmFseXplKHRyYWNlSWRzOiBzdHJpbmdbXSk6IFByb21pc2U8QnVsa0FuYWx5c2lzUmVzdWx0PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxCdWxrQW5hbHlzaXNSZXN1bHQ+KCcvdHJhbnNjcmlwdC1wYXR0ZXJucy9idWxrLWFuYWx5emUnLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGJvZHk6IHsgdHJhY2VJZHMgfSxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhdmFpbGFibGUgcGF0dGVybiBjYXRlZ29yaWVzIHdpdGggZGVzY3JpcHRpb25zXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgY2F0ZWdvcmllcyA9IGF3YWl0IHRyYW5zY3JpcHRQYXR0ZXJucy5nZXRDYXRlZ29yaWVzKCk7XG4gICAqIGZvciAoY29uc3QgY2F0ZWdvcnkgb2YgY2F0ZWdvcmllcykge1xuICAgKiAgIGNvbnNvbGUubG9nKGAke2NhdGVnb3J5Lm5hbWV9OiAke2NhdGVnb3J5LmRlc2NyaXB0aW9ufWApO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0Q2F0ZWdvcmllcygpOiBQcm9taXNlPFBhdHRlcm5DYXRlZ29yeUluZm9bXT4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8UGF0dGVybkNhdGVnb3J5SW5mb1tdPihcbiAgICAgICcvdHJhbnNjcmlwdC1wYXR0ZXJucy9jYXRlZ29yaWVzJyxcbiAgICAgIHsgYXBpVmVyc2lvbjogJ3YxJyB9XG4gICAgKTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGJ1aWx0LWluIHBhdHRlcm5zXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgcGF0dGVybnMgPSBhd2FpdCB0cmFuc2NyaXB0UGF0dGVybnMuZ2V0QnVpbHRJblBhdHRlcm5zKCk7XG4gICAqIGNvbnN0IGZydXN0cmF0aW9uUGF0dGVybnMgPSBwYXR0ZXJucy5maWx0ZXIocCA9PiBwLmNhdGVnb3J5ID09PSAnZnJ1c3RyYXRpb24nKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBnZXRCdWlsdEluUGF0dGVybnMoKTogUHJvbWlzZTxCdWlsdEluUGF0dGVybltdPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxCdWlsdEluUGF0dGVybltdPihcbiAgICAgICcvdHJhbnNjcmlwdC1wYXR0ZXJucy9idWlsdC1pbicsXG4gICAgICB7IGFwaVZlcnNpb246ICd2MScgfVxuICAgICk7XG4gIH0sXG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ2hlY2sgaWYgYW5hbHlzaXMgcmVzdWx0IGluZGljYXRlcyBoaWdoIHJpc2tcbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gQW5hbHlzaXMgcmVzdWx0IHRvIGNoZWNrXG4gKiBAcGFyYW0gdGhyZXNob2xkIC0gUmlzayBzY29yZSB0aHJlc2hvbGQgKGRlZmF1bHQgNzApXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSByZXN1bHQgaW5kaWNhdGVzIGhpZ2ggcmlza1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNIaWdoUmlzayhyZXN1bHQ6IEFuYWx5c2lzUmVzdWx0LCB0aHJlc2hvbGQgPSA3MCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVzdWx0LnJpc2tTY29yZSA+PSB0aHJlc2hvbGQ7XG59XG5cbi8qKlxuICogR2V0IG1hdGNoZXMgYnkgY2F0ZWdvcnlcbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gQW5hbHlzaXMgcmVzdWx0XG4gKiBAcGFyYW0gY2F0ZWdvcnkgLSBQYXR0ZXJuIGNhdGVnb3J5IHRvIGZpbHRlciBieVxuICogQHJldHVybnMgRmlsdGVyZWQgcGF0dGVybiBtYXRjaGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXRjaGVzQnlDYXRlZ29yeShcbiAgcmVzdWx0OiBBbmFseXNpc1Jlc3VsdCxcbiAgY2F0ZWdvcnk6IFBhdHRlcm5DYXRlZ29yeVxuKTogUGF0dGVybk1hdGNoW10ge1xuICByZXR1cm4gcmVzdWx0Lm1hdGNoZXMuZmlsdGVyKG0gPT4gbS5jYXRlZ29yeSA9PT0gY2F0ZWdvcnkpO1xufVxuXG4vKipcbiAqIEdldCBjcml0aWNhbCBpbnNpZ2h0cyBmcm9tIGFuYWx5c2lzXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIEFuYWx5c2lzIHJlc3VsdFxuICogQHJldHVybnMgQ3JpdGljYWwgc2V2ZXJpdHkgaW5zaWdodHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENyaXRpY2FsSW5zaWdodHMocmVzdWx0OiBBbmFseXNpc1Jlc3VsdCk6IFBhdHRlcm5JbnNpZ2h0W10ge1xuICByZXR1cm4gcmVzdWx0Lmluc2lnaHRzLmZpbHRlcihpID0+IGkuc2V2ZXJpdHkgPT09ICdjcml0aWNhbCcpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGFuYWx5c2lzIGRldGVjdGVkIFBJSVxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBBbmFseXNpcyByZXN1bHRcbiAqIEByZXR1cm5zIFdoZXRoZXIgUElJIHdhcyBkZXRlY3RlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzUGlpRXhwb3N1cmUocmVzdWx0OiBBbmFseXNpc1Jlc3VsdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVzdWx0Lm1hdGNoZXMuc29tZShtID0+IG0uY2F0ZWdvcnkgPT09ICdwaWlfZXhwb3N1cmUnKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbmFseXNpcyBkZXRlY3RlZCBmcnVzdHJhdGlvblxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBBbmFseXNpcyByZXN1bHRcbiAqIEByZXR1cm5zIFdoZXRoZXIgZnJ1c3RyYXRpb24gd2FzIGRldGVjdGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNGcnVzdHJhdGlvblNpZ25hbHMocmVzdWx0OiBBbmFseXNpc1Jlc3VsdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVzdWx0Lm1hdGNoZXMuc29tZShtID0+IG0uY2F0ZWdvcnkgPT09ICdmcnVzdHJhdGlvbicpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGFuYWx5c2lzIGRldGVjdGVkIGVzY2FsYXRpb24gcmVxdWVzdFxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBBbmFseXNpcyByZXN1bHRcbiAqIEByZXR1cm5zIFdoZXRoZXIgZXNjYWxhdGlvbiB3YXMgcmVxdWVzdGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNFc2NhbGF0aW9uUmVxdWVzdChyZXN1bHQ6IEFuYWx5c2lzUmVzdWx0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXN1bHQubWF0Y2hlcy5zb21lKG0gPT4gbS5jYXRlZ29yeSA9PT0gJ2VzY2FsYXRpb24nKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgY2F0ZWdvcnkgZGlzdHJpYnV0aW9uXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIEFuYWx5c2lzIHJlc3VsdFxuICogQHJldHVybnMgT2JqZWN0IHdpdGggY291bnRzIHBlciBjYXRlZ29yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2F0ZWdvcnlEaXN0cmlidXRpb24ocmVzdWx0OiBBbmFseXNpc1Jlc3VsdCk6IFJlY29yZDxQYXR0ZXJuQ2F0ZWdvcnksIG51bWJlcj4ge1xuICBjb25zdCBkaXN0cmlidXRpb246IFJlY29yZDxQYXR0ZXJuQ2F0ZWdvcnksIG51bWJlcj4gPSB7XG4gICAgZnJ1c3RyYXRpb246IDAsXG4gICAgY29uZnVzaW9uOiAwLFxuICAgIHN1Y2Nlc3M6IDAsXG4gICAgZmFpbHVyZTogMCxcbiAgICBlc2NhbGF0aW9uOiAwLFxuICAgIHBpaV9leHBvc3VyZTogMCxcbiAgICBoYWxsdWNpbmF0aW9uOiAwLFxuICAgIGN1c3RvbTogMCxcbiAgfTtcblxuICBmb3IgKGNvbnN0IG1hdGNoIG9mIHJlc3VsdC5tYXRjaGVzKSB7XG4gICAgZGlzdHJpYnV0aW9uW21hdGNoLmNhdGVnb3J5XSsrO1xuICB9XG5cbiAgcmV0dXJuIGRpc3RyaWJ1dGlvbjtcbn1cblxuLyoqXG4gKiBHZXQgYWN0aW9uYWJsZSByZWNvbW1lbmRhdGlvbnMgZnJvbSBpbnNpZ2h0c1xuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBBbmFseXNpcyByZXN1bHRcbiAqIEByZXR1cm5zIEFycmF5IG9mIHJlY29tbWVuZGF0aW9uIHN0cmluZ3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlY29tbWVuZGF0aW9ucyhyZXN1bHQ6IEFuYWx5c2lzUmVzdWx0KTogc3RyaW5nW10ge1xuICByZXR1cm4gcmVzdWx0Lmluc2lnaHRzXG4gICAgLmZpbHRlcihpID0+IGkucmVjb21tZW5kYXRpb24pXG4gICAgLm1hcChpID0+IGkucmVjb21tZW5kYXRpb24gYXMgc3RyaW5nKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgb3ZlcmFsbCBzZW50aW1lbnQgZnJvbSBhbmFseXNpc1xuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBBbmFseXNpcyByZXN1bHRcbiAqIEByZXR1cm5zIFNlbnRpbWVudCBzY29yZSAoLTEgdG8gMSkgb3IgbnVsbCBpZiBub3QgYXZhaWxhYmxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPdmVyYWxsU2VudGltZW50KHJlc3VsdDogQW5hbHlzaXNSZXN1bHQpOiBudW1iZXIgfCBudWxsIHtcbiAgcmV0dXJuIHJlc3VsdC5zZW50aW1lbnRTY29yZXM/Lm92ZXJhbGwgPz8gbnVsbDtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgY29udmVyc2F0aW9uIG5lZWRzIGF0dGVudGlvbiBiYXNlZCBvbiBwYXR0ZXJuc1xuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBBbmFseXNpcyByZXN1bHRcbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGNvbnZlcnNhdGlvbiBuZWVkcyBhdHRlbnRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5lZWRzQXR0ZW50aW9uKHJlc3VsdDogQW5hbHlzaXNSZXN1bHQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICByZXN1bHQucmlza1Njb3JlID49IDUwIHx8XG4gICAgaGFzUGlpRXhwb3N1cmUocmVzdWx0KSB8fFxuICAgIGhhc0VzY2FsYXRpb25SZXF1ZXN0KHJlc3VsdCkgfHxcbiAgICByZXN1bHQuaW5zaWdodHMuc29tZShpID0+IGkuc2V2ZXJpdHkgPT09ICdjcml0aWNhbCcpXG4gICk7XG59XG5cbi8qKlxuICogR2V0IHNldmVyaXR5IGxldmVsIGFzIG51bWVyaWMgdmFsdWVcbiAqXG4gKiBAcGFyYW0gc2V2ZXJpdHkgLSBQYXR0ZXJuIHNldmVyaXR5XG4gKiBAcmV0dXJucyBOdW1lcmljIHNldmVyaXR5ICgxLTMpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZXZlcml0eUxldmVsKHNldmVyaXR5OiBQYXR0ZXJuU2V2ZXJpdHkpOiBudW1iZXIge1xuICBzd2l0Y2ggKHNldmVyaXR5KSB7XG4gICAgY2FzZSAnaW5mbyc6IHJldHVybiAxO1xuICAgIGNhc2UgJ3dhcm5pbmcnOiByZXR1cm4gMjtcbiAgICBjYXNlICdjcml0aWNhbCc6IHJldHVybiAzO1xuICAgIGRlZmF1bHQ6IHJldHVybiAwO1xuICB9XG59XG5cbi8qKlxuICogU29ydCBtYXRjaGVzIGJ5IHNldmVyaXR5IChjcml0aWNhbCBmaXJzdClcbiAqXG4gKiBAcGFyYW0gbWF0Y2hlcyAtIFBhdHRlcm4gbWF0Y2hlcyB0byBzb3J0XG4gKiBAcmV0dXJucyBTb3J0ZWQgbWF0Y2hlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc29ydE1hdGNoZXNCeVNldmVyaXR5KG1hdGNoZXM6IFBhdHRlcm5NYXRjaFtdKTogUGF0dGVybk1hdGNoW10ge1xuICByZXR1cm4gWy4uLm1hdGNoZXNdLnNvcnQoKGEsIGIpID0+IGdldFNldmVyaXR5TGV2ZWwoYi5zZXZlcml0eSkgLSBnZXRTZXZlcml0eUxldmVsKGEuc2V2ZXJpdHkpKTtcbn1cbiJdfQ==
@@ -4,26 +4,100 @@
4
4
  * Centralized HTTP client with authentication and error handling
5
5
  */
6
6
  export interface RequestOptions {
7
- method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
7
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
8
8
  body?: unknown;
9
9
  headers?: Record<string, string>;
10
10
  /** Override API version for this request */
11
- apiVersion?: 'v1' | 'v3';
11
+ apiVersion?: 'v1' | 'v2' | 'v3';
12
+ /** Override max retries for this request */
13
+ maxRetries?: number;
14
+ /** Request timeout in milliseconds */
15
+ timeout?: number;
12
16
  }
13
17
  /**
14
- * Make an authenticated API request
18
+ * Make an authenticated API request with retry logic
15
19
  */
16
20
  export declare function apiRequest<T>(path: string, options?: RequestOptions): Promise<T>;
17
21
  /**
18
22
  * Make an API request and extract data from response wrapper
19
23
  */
20
24
  export declare function apiRequestWithData<T>(path: string, options?: RequestOptions): Promise<T>;
21
- export declare class ThinkHiveApiError extends Error {
22
- readonly statusCode: number;
23
- readonly code?: string | undefined;
24
- constructor(message: string, statusCode: number, code?: string | undefined);
25
+ /**
26
+ * Base error class for ThinkHive SDK errors
27
+ */
28
+ export declare class ThinkHiveError extends Error {
29
+ readonly code: string;
30
+ readonly statusCode?: number | undefined;
31
+ readonly details?: Record<string, unknown> | undefined;
32
+ constructor(message: string, code: string, statusCode?: number | undefined, details?: Record<string, unknown> | undefined);
33
+ }
34
+ /**
35
+ * API request error - returned from ThinkHive server
36
+ */
37
+ export declare class ThinkHiveApiError extends ThinkHiveError {
38
+ constructor(message: string, statusCode: number, code?: string);
25
39
  }
26
- export declare class ThinkHiveValidationError extends Error {
40
+ /**
41
+ * Validation error - invalid input parameters
42
+ */
43
+ export declare class ThinkHiveValidationError extends ThinkHiveError {
27
44
  readonly field?: string | undefined;
28
45
  constructor(message: string, field?: string | undefined);
29
46
  }
47
+ /**
48
+ * Permission denied error - API key lacks required permissions
49
+ * @example
50
+ * ```typescript
51
+ * try {
52
+ * await thinkHive.traces.create(...);
53
+ * } catch (error) {
54
+ * if (error instanceof PermissionDeniedError) {
55
+ * console.log('API key needs write permission');
56
+ * }
57
+ * }
58
+ * ```
59
+ */
60
+ export declare class PermissionDeniedError extends ThinkHiveError {
61
+ constructor(message: string, details?: Record<string, unknown>);
62
+ }
63
+ /**
64
+ * Agent scope violation error - API key not authorized for this agent
65
+ * @example
66
+ * ```typescript
67
+ * // Create key scoped to specific agents
68
+ * const key = await thinkHive.apiKeys.create({
69
+ * name: 'Agent A Key',
70
+ * allowedAgentIds: ['agent-a-id']
71
+ * });
72
+ *
73
+ * // Attempting to use for Agent B will throw AgentScopeError
74
+ * ```
75
+ */
76
+ export declare class AgentScopeError extends ThinkHiveError {
77
+ constructor(agentId: string, allowedAgents: string[]);
78
+ }
79
+ /**
80
+ * Rate limit exceeded error
81
+ * @example
82
+ * ```typescript
83
+ * try {
84
+ * await thinkHive.traces.create(...);
85
+ * } catch (error) {
86
+ * if (error instanceof RateLimitError) {
87
+ * // Wait and retry
88
+ * await sleep(error.retryAfter);
89
+ * await thinkHive.traces.create(...);
90
+ * }
91
+ * }
92
+ * ```
93
+ */
94
+ export declare class RateLimitError extends ThinkHiveError {
95
+ readonly retryAfter: number;
96
+ constructor(retryAfter: number);
97
+ }
98
+ /**
99
+ * IP whitelist violation error
100
+ */
101
+ export declare class IpWhitelistError extends ThinkHiveError {
102
+ constructor(clientIp: string);
103
+ }