File size: 4,431 Bytes
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4a41fa
c1feb60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
"""Custom exceptions for Headroom.

This module provides explicit exception classes for better error handling
and debugging. All exceptions inherit from HeadroomError, making it easy
to catch all Headroom-related errors.

Example:
    from headroom import HeadroomClient, HeadroomError, ConfigurationError

    try:
        client = HeadroomClient(...)
        client.validate_setup()
    except ConfigurationError as e:
        print(f"Configuration problem: {e}")
    except HeadroomError as e:
        print(f"Headroom error: {e}")
"""

from __future__ import annotations

from typing import Any


class HeadroomError(Exception):
    """Base exception for all Headroom errors.

    All Headroom exceptions inherit from this class, making it easy
    to catch any Headroom-related error:

        try:
            client.chat.completions.create(...)
        except HeadroomError as e:
            # Handle any Headroom error
            pass
    """

    def __init__(self, message: str, details: dict[str, Any] | None = None):
        super().__init__(message)
        self.message = message
        self.details = details or {}

    def __str__(self) -> str:
        if self.details:
            detail_str = ", ".join(f"{k}={v}" for k, v in self.details.items())
            return f"{self.message} ({detail_str})"
        return self.message


class ConfigurationError(HeadroomError):
    """Raised when Headroom is misconfigured.

    This includes:
    - Invalid mode values
    - Missing required configuration
    - Incompatible configuration combinations

    Example:
        ConfigurationError(
            "Invalid mode 'foo'",
            details={"valid_modes": ["audit", "optimize"]}
        )
    """

    pass


class ProviderError(HeadroomError):
    """Raised when there's an issue with the LLM provider.

    This includes:
    - Provider not recognized
    - Provider-specific configuration issues
    - Token counter errors

    Example:
        ProviderError(
            "Unknown provider",
            details={"provider": "foo", "known_providers": ["openai", "anthropic"]}
        )
    """

    pass


class StorageError(HeadroomError):
    """Raised when there's an issue with metrics storage.

    This includes:
    - Database connection failures
    - Invalid storage URL
    - Write failures

    Example:
        StorageError(
            "Cannot connect to database",
            details={"url": "sqlite:///foo.db", "error": "Permission denied"}
        )
    """

    pass


class CompressionError(HeadroomError):
    """Raised when compression fails.

    This includes:
    - Parse errors in tool outputs
    - Invalid JSON structures
    - Compression strategy failures

    Example:
        CompressionError(
            "Failed to parse tool output",
            details={"tool_name": "search_api", "content_preview": "..."}
        )
    """

    pass


class TokenizationError(HeadroomError):
    """Raised when token counting fails.

    This includes:
    - Unknown model for tokenization
    - Encoding errors
    - Tiktoken/tokenizer loading failures

    Example:
        TokenizationError(
            "Unknown model for tokenization",
            details={"model": "gpt-99", "fallback_used": True}
        )
    """

    pass


class CacheError(HeadroomError):
    """Raised when caching operations fail.

    This includes:
    - Cache store errors
    - Retrieval failures
    - CCR (Compress-Cache-Retrieve) errors

    Example:
        CacheError(
            "Cache entry expired",
            details={"hash": "abc123", "ttl": 300}
        )
    """

    pass


class ValidationError(HeadroomError):
    """Raised when setup validation fails.

    This is raised by validate_setup() when the configuration
    or environment is not properly set up.

    Example:
        ValidationError(
            "Setup validation failed",
            details={
                "provider_ok": True,
                "storage_ok": False,
                "storage_error": "Cannot write to database"
            }
        )
    """

    pass


class TransformError(HeadroomError):
    """Raised when a transform fails to apply.

    This includes:
    - SmartCrusher failures
    - RollingWindow errors
    - Pipeline errors

    Example:
        TransformError(
            "Transform failed",
            details={"transform": "smart_crusher", "reason": "..."}
        )
    """

    pass