avenix 0.1.0__tar.gz

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.
avenix-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 AgentForge Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
avenix-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: avenix
3
+ Version: 0.1.0
4
+ Summary: Avenix is a focused Python tracing library for AI requests with beautiful terminal output
5
+ Author: Avenix Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/avenix/avenix
8
+ Project-URL: Repository, https://github.com/avenix/avenix
9
+ Project-URL: Documentation, https://github.com/avenix/avenix#readme
10
+ Keywords: ai,tracing,llm,monitoring,openai,anthropic
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: System :: Monitoring
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: pydantic<3.0,>=2.0
23
+ Requires-Dist: rich<14.0,>=13.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
26
+ Requires-Dist: hypothesis<7.0,>=6.0; extra == "dev"
27
+ Requires-Dist: pytest-cov<5.0,>=4.0; extra == "dev"
28
+ Requires-Dist: pytest-mock<4.0,>=3.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # Avenix v0.1
32
+
33
+ A Python tracing library for AI/LLM requests with beautiful terminal output.
34
+
35
+ Avenix provides a decorator-based API for tracing AI model requests, automatically capturing execution metrics like timing, token usage, and costs, then displaying them in richly formatted terminal output.
36
+
37
+ ## Overview
38
+
39
+ Avenix simplifies monitoring AI/LLM requests by:
40
+ - **Automatic Capture**: Uses a simple `@trace` decorator to automatically capture request metrics
41
+ - **Beautiful Display**: Renders trace information in a formatted terminal panel with colors and separators
42
+ - **Multi-Provider Support**: Works with OpenAI and Anthropic model responses out of the box
43
+ - **Cost Tracking**: Automatically calculates request costs based on model pricing
44
+ - **Extensible**: Easy to add custom extractors for new AI providers
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install avenix
50
+ ```
51
+
52
+ ## Requirements
53
+
54
+ - Python 3.11+
55
+ - pydantic ^2.0
56
+ - rich ^13.0
57
+
58
+ ## Quick Start
59
+
60
+ ### Using the @trace Decorator
61
+
62
+ The simplest way to use Avenix is with the `@trace` decorator:
63
+
64
+ ```python
65
+ from avenix import trace
66
+ from openai import OpenAI
67
+
68
+ client = OpenAI()
69
+
70
+ @trace
71
+ def get_gpt_response(prompt: str):
72
+ """Call GPT-4 with the given prompt."""
73
+ response = client.chat.completions.create(
74
+ model="gpt-4",
75
+ messages=[{"role": "user", "content": prompt}]
76
+ )
77
+ return response
78
+
79
+ # When you call the function, Avenix will automatically:
80
+ # 1. Measure execution time
81
+ # 2. Extract model, tokens, and response from the result
82
+ # 3. Calculate cost based on token usage
83
+ # 4. Display formatted trace output to terminal
84
+ result = get_gpt_response("What is machine learning?")
85
+ ```
86
+
87
+ ### Manual Trace Creation
88
+
89
+ For more control, you can manually create traces using the `Tracer` API:
90
+
91
+ ```python
92
+ from avenix import Tracer
93
+
94
+ tracer = Tracer()
95
+
96
+ # Later, manually create a trace with explicit values
97
+ tracer.create_trace(
98
+ model="gpt-4",
99
+ latency=2.5,
100
+ input_tokens=150,
101
+ output_tokens=300,
102
+ cost=0.045,
103
+ prompt="What is AI?",
104
+ response="AI is artificial intelligence..."
105
+ )
106
+ ```
107
+
108
+ ## Supported Models
109
+
110
+ Avenix includes built-in support for:
111
+
112
+ ### OpenAI
113
+ - gpt-4
114
+ - gpt-4-turbo
115
+ - gpt-3.5-turbo
116
+
117
+ ### Anthropic
118
+ - claude-3-opus
119
+ - claude-3-sonnet
120
+ - claude-3-haiku
121
+
122
+ ## Features in v0.1
123
+
124
+ ✅ Decorator-based tracing API
125
+ ✅ Automatic timing measurement with perf_counter
126
+ ✅ OpenAI and Anthropic response extraction
127
+ ✅ Model pricing table and cost calculation
128
+ ✅ Beautiful terminal output with rich formatting
129
+ ✅ Error handling and graceful fallbacks
130
+ ✅ Property-based test suite for correctness verification
131
+
132
+ ## Out of Scope for v0.1
133
+
134
+ The following features are planned for future releases:
135
+
136
+ - Custom formatter plugins
137
+ - Database/file persistence of traces
138
+ - Trace filtering and search
139
+ - Performance statistics aggregation
140
+ - Integration with external logging services
141
+ - Support for additional AI providers
142
+ - Rate limiting and quota management
143
+ - Async/await support
144
+
145
+ ## Documentation
146
+
147
+ ### API Reference
148
+
149
+ #### @trace Decorator
150
+
151
+ ```python
152
+ @trace
153
+ def your_function():
154
+ # ... your code that calls an AI model
155
+ return response
156
+ ```
157
+
158
+ The `@trace` decorator:
159
+ - Measures execution time with `time.perf_counter()`
160
+ - Captures the function result
161
+ - Calls the global `Tracer` instance to extract data and display trace
162
+ - Propagates exceptions without suppression
163
+ - Preserves the original function's return value and metadata
164
+
165
+ #### Tracer Class
166
+
167
+ ```python
168
+ from avenix import Tracer
169
+
170
+ tracer = Tracer(logger=None, formatter=None)
171
+ ```
172
+
173
+ Methods:
174
+ - `capture_trace(result, latency, func_name=None)`: Capture and display a trace from function execution
175
+ - `create_trace(model, latency, input_tokens, output_tokens, cost, prompt, response)`: Manually create and display a trace
176
+
177
+ ### TraceModel
178
+
179
+ The `TraceModel` class represents a single trace with validation:
180
+
181
+ Fields:
182
+ - `model` (str): Name of the AI model
183
+ - `latency` (float): Execution time in seconds (rounded to 2 decimals)
184
+ - `input_tokens` (int): Number of input tokens (must be non-negative)
185
+ - `output_tokens` (int): Number of output tokens (must be non-negative)
186
+ - `cost` (float): Request cost in dollars (rounded to 4 decimals, must be non-negative)
187
+ - `prompt` (str): Input prompt text (defaults to empty string)
188
+ - `response` (str): Model response text (defaults to empty string)
189
+
190
+ ## Examples
191
+
192
+ See the `examples/` directory for complete working examples:
193
+
194
+ - `openai_example.py`: Using @trace with OpenAI API
195
+ - `anthropic_example.py`: Using @trace with Anthropic API
196
+ - `manual_trace.py`: Creating traces manually with Tracer API
197
+
198
+ ## Testing
199
+
200
+ Avenix includes a comprehensive test suite with property-based tests:
201
+
202
+ ```bash
203
+ pytest tests/ -v # Run all tests
204
+ pytest tests/ --cov # Run with coverage report
205
+ pytest tests/test_models.py -v # Run specific test file
206
+ ```
207
+
208
+ Test coverage targets:
209
+ - Core modules (decorator, tracer, models, formatter, extractors): >90%
210
+ - Property-based tests for 16 correctness properties
211
+ - Unit tests for all feature components
212
+
213
+ ## Architecture
214
+
215
+ Avenix follows a layered architecture:
216
+
217
+ 1. **Models Layer** (`models.py`): Defines `TraceModel` with Pydantic validation
218
+ 2. **Decorator Layer** (`decorator.py`): Provides `@trace` decorator for wrapping functions
219
+ 3. **Tracer Layer** (`tracer.py`): Core orchestration with optional custom logger/formatter
220
+ 4. **Extraction Layer** (`extractors.py`): Provider-specific response extractors
221
+ 5. **Formatting Layer** (`formatter.py`): Beautiful terminal output with rich library
222
+ 6. **Logging Layer** (`logger.py`): Terminal display with fallback handling
223
+
224
+ ## Error Handling
225
+
226
+ Avenix is designed to be resilient to errors:
227
+
228
+ - **Extraction Failures**: If response format doesn't match known providers, uses sensible defaults
229
+ - **Validation Failures**: If TraceModel validation fails, falls back to defaults
230
+ - **Rendering Failures**: If rich formatting fails, falls back to basic print output
231
+ - **Exception Propagation**: Errors in traced functions propagate normally without suppression
232
+
233
+ ## Contributing
234
+
235
+ This is a v0.1 release. Feedback and contributions are welcome!
236
+
237
+ ## API Reference
238
+
239
+ For detailed API documentation, see [API.md](API.md).
240
+
241
+ ## License
242
+
243
+ MIT License - See LICENSE file for details
244
+
245
+ ## Changelog
246
+
247
+ See CHANGELOG.md for version history and release notes
avenix-0.1.0/README.md ADDED
@@ -0,0 +1,217 @@
1
+ # Avenix v0.1
2
+
3
+ A Python tracing library for AI/LLM requests with beautiful terminal output.
4
+
5
+ Avenix provides a decorator-based API for tracing AI model requests, automatically capturing execution metrics like timing, token usage, and costs, then displaying them in richly formatted terminal output.
6
+
7
+ ## Overview
8
+
9
+ Avenix simplifies monitoring AI/LLM requests by:
10
+ - **Automatic Capture**: Uses a simple `@trace` decorator to automatically capture request metrics
11
+ - **Beautiful Display**: Renders trace information in a formatted terminal panel with colors and separators
12
+ - **Multi-Provider Support**: Works with OpenAI and Anthropic model responses out of the box
13
+ - **Cost Tracking**: Automatically calculates request costs based on model pricing
14
+ - **Extensible**: Easy to add custom extractors for new AI providers
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install avenix
20
+ ```
21
+
22
+ ## Requirements
23
+
24
+ - Python 3.11+
25
+ - pydantic ^2.0
26
+ - rich ^13.0
27
+
28
+ ## Quick Start
29
+
30
+ ### Using the @trace Decorator
31
+
32
+ The simplest way to use Avenix is with the `@trace` decorator:
33
+
34
+ ```python
35
+ from avenix import trace
36
+ from openai import OpenAI
37
+
38
+ client = OpenAI()
39
+
40
+ @trace
41
+ def get_gpt_response(prompt: str):
42
+ """Call GPT-4 with the given prompt."""
43
+ response = client.chat.completions.create(
44
+ model="gpt-4",
45
+ messages=[{"role": "user", "content": prompt}]
46
+ )
47
+ return response
48
+
49
+ # When you call the function, Avenix will automatically:
50
+ # 1. Measure execution time
51
+ # 2. Extract model, tokens, and response from the result
52
+ # 3. Calculate cost based on token usage
53
+ # 4. Display formatted trace output to terminal
54
+ result = get_gpt_response("What is machine learning?")
55
+ ```
56
+
57
+ ### Manual Trace Creation
58
+
59
+ For more control, you can manually create traces using the `Tracer` API:
60
+
61
+ ```python
62
+ from avenix import Tracer
63
+
64
+ tracer = Tracer()
65
+
66
+ # Later, manually create a trace with explicit values
67
+ tracer.create_trace(
68
+ model="gpt-4",
69
+ latency=2.5,
70
+ input_tokens=150,
71
+ output_tokens=300,
72
+ cost=0.045,
73
+ prompt="What is AI?",
74
+ response="AI is artificial intelligence..."
75
+ )
76
+ ```
77
+
78
+ ## Supported Models
79
+
80
+ Avenix includes built-in support for:
81
+
82
+ ### OpenAI
83
+ - gpt-4
84
+ - gpt-4-turbo
85
+ - gpt-3.5-turbo
86
+
87
+ ### Anthropic
88
+ - claude-3-opus
89
+ - claude-3-sonnet
90
+ - claude-3-haiku
91
+
92
+ ## Features in v0.1
93
+
94
+ ✅ Decorator-based tracing API
95
+ ✅ Automatic timing measurement with perf_counter
96
+ ✅ OpenAI and Anthropic response extraction
97
+ ✅ Model pricing table and cost calculation
98
+ ✅ Beautiful terminal output with rich formatting
99
+ ✅ Error handling and graceful fallbacks
100
+ ✅ Property-based test suite for correctness verification
101
+
102
+ ## Out of Scope for v0.1
103
+
104
+ The following features are planned for future releases:
105
+
106
+ - Custom formatter plugins
107
+ - Database/file persistence of traces
108
+ - Trace filtering and search
109
+ - Performance statistics aggregation
110
+ - Integration with external logging services
111
+ - Support for additional AI providers
112
+ - Rate limiting and quota management
113
+ - Async/await support
114
+
115
+ ## Documentation
116
+
117
+ ### API Reference
118
+
119
+ #### @trace Decorator
120
+
121
+ ```python
122
+ @trace
123
+ def your_function():
124
+ # ... your code that calls an AI model
125
+ return response
126
+ ```
127
+
128
+ The `@trace` decorator:
129
+ - Measures execution time with `time.perf_counter()`
130
+ - Captures the function result
131
+ - Calls the global `Tracer` instance to extract data and display trace
132
+ - Propagates exceptions without suppression
133
+ - Preserves the original function's return value and metadata
134
+
135
+ #### Tracer Class
136
+
137
+ ```python
138
+ from avenix import Tracer
139
+
140
+ tracer = Tracer(logger=None, formatter=None)
141
+ ```
142
+
143
+ Methods:
144
+ - `capture_trace(result, latency, func_name=None)`: Capture and display a trace from function execution
145
+ - `create_trace(model, latency, input_tokens, output_tokens, cost, prompt, response)`: Manually create and display a trace
146
+
147
+ ### TraceModel
148
+
149
+ The `TraceModel` class represents a single trace with validation:
150
+
151
+ Fields:
152
+ - `model` (str): Name of the AI model
153
+ - `latency` (float): Execution time in seconds (rounded to 2 decimals)
154
+ - `input_tokens` (int): Number of input tokens (must be non-negative)
155
+ - `output_tokens` (int): Number of output tokens (must be non-negative)
156
+ - `cost` (float): Request cost in dollars (rounded to 4 decimals, must be non-negative)
157
+ - `prompt` (str): Input prompt text (defaults to empty string)
158
+ - `response` (str): Model response text (defaults to empty string)
159
+
160
+ ## Examples
161
+
162
+ See the `examples/` directory for complete working examples:
163
+
164
+ - `openai_example.py`: Using @trace with OpenAI API
165
+ - `anthropic_example.py`: Using @trace with Anthropic API
166
+ - `manual_trace.py`: Creating traces manually with Tracer API
167
+
168
+ ## Testing
169
+
170
+ Avenix includes a comprehensive test suite with property-based tests:
171
+
172
+ ```bash
173
+ pytest tests/ -v # Run all tests
174
+ pytest tests/ --cov # Run with coverage report
175
+ pytest tests/test_models.py -v # Run specific test file
176
+ ```
177
+
178
+ Test coverage targets:
179
+ - Core modules (decorator, tracer, models, formatter, extractors): >90%
180
+ - Property-based tests for 16 correctness properties
181
+ - Unit tests for all feature components
182
+
183
+ ## Architecture
184
+
185
+ Avenix follows a layered architecture:
186
+
187
+ 1. **Models Layer** (`models.py`): Defines `TraceModel` with Pydantic validation
188
+ 2. **Decorator Layer** (`decorator.py`): Provides `@trace` decorator for wrapping functions
189
+ 3. **Tracer Layer** (`tracer.py`): Core orchestration with optional custom logger/formatter
190
+ 4. **Extraction Layer** (`extractors.py`): Provider-specific response extractors
191
+ 5. **Formatting Layer** (`formatter.py`): Beautiful terminal output with rich library
192
+ 6. **Logging Layer** (`logger.py`): Terminal display with fallback handling
193
+
194
+ ## Error Handling
195
+
196
+ Avenix is designed to be resilient to errors:
197
+
198
+ - **Extraction Failures**: If response format doesn't match known providers, uses sensible defaults
199
+ - **Validation Failures**: If TraceModel validation fails, falls back to defaults
200
+ - **Rendering Failures**: If rich formatting fails, falls back to basic print output
201
+ - **Exception Propagation**: Errors in traced functions propagate normally without suppression
202
+
203
+ ## Contributing
204
+
205
+ This is a v0.1 release. Feedback and contributions are welcome!
206
+
207
+ ## API Reference
208
+
209
+ For detailed API documentation, see [API.md](API.md).
210
+
211
+ ## License
212
+
213
+ MIT License - See LICENSE file for details
214
+
215
+ ## Changelog
216
+
217
+ See CHANGELOG.md for version history and release notes
@@ -0,0 +1,11 @@
1
+ """
2
+ Avenix - Python tracing library for AI requests.
3
+
4
+ Provides decorator-based tracing for AI/LLM requests with beautiful terminal output.
5
+ """
6
+
7
+ from .decorator import trace
8
+ from .tracer import Tracer
9
+
10
+ __version__ = "0.1.0"
11
+ __all__ = ["trace", "Tracer"]
@@ -0,0 +1,62 @@
1
+ # Trace decorator implementation
2
+
3
+ import functools
4
+ import time
5
+ from typing import Callable, Any
6
+
7
+
8
+ def trace(func: Callable) -> Callable:
9
+ """
10
+ Decorator that traces AI request function execution.
11
+
12
+ Captures timing, model info, tokens, cost, prompt, and response.
13
+ Displays formatted trace to terminal after execution.
14
+
15
+ Args:
16
+ func: The function to trace (should return AI response object)
17
+
18
+ Returns:
19
+ Wrapped function with identical signature and return type
20
+
21
+ Example:
22
+ @trace
23
+ def call_openai(prompt: str):
24
+ return client.chat.completions.create(
25
+ model="gpt-4",
26
+ messages=[{"role": "user", "content": prompt}]
27
+ )
28
+ """
29
+ from .tracer import Tracer
30
+
31
+ # Create tracer instance once at decoration time
32
+ tracer = Tracer()
33
+
34
+ @functools.wraps(func)
35
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
36
+ # Record start time with high precision
37
+ start_time = time.perf_counter()
38
+
39
+ try:
40
+ # Execute the wrapped function
41
+ result = func(*args, **kwargs)
42
+
43
+ # Calculate latency
44
+ end_time = time.perf_counter()
45
+ latency = end_time - start_time
46
+
47
+ # Capture and display trace
48
+ tracer.capture_trace(
49
+ result=result,
50
+ latency=latency,
51
+ func_name=func.__name__
52
+ )
53
+
54
+ # Return original result unchanged
55
+ return result
56
+
57
+ except Exception:
58
+ # Propagate exceptions without suppression
59
+ # No trace is captured on failure
60
+ raise
61
+
62
+ return wrapper
@@ -0,0 +1,81 @@
1
+ # Provider-specific extraction logic for AI responses
2
+
3
+ import logging
4
+ from abc import ABC, abstractmethod
5
+ from typing import Any, Dict
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class ResponseExtractor(ABC):
11
+ """Abstract base class for AI response extractors."""
12
+
13
+ @abstractmethod
14
+ def can_extract(self, result: Any) -> bool:
15
+ """Check if this extractor can handle the given result."""
16
+ ...
17
+
18
+ @abstractmethod
19
+ def extract(self, result: Any) -> Dict[str, Any]:
20
+ """Extract trace data from result."""
21
+ ...
22
+
23
+
24
+ class OpenAIExtractor(ResponseExtractor):
25
+ """Extractor for OpenAI response format."""
26
+
27
+ def can_extract(self, result: Any) -> bool:
28
+ """Check if result matches OpenAI format."""
29
+ usage = getattr(result, 'usage', None)
30
+ choices = getattr(result, 'choices', None)
31
+
32
+ return (
33
+ hasattr(result, 'model') and
34
+ hasattr(usage, 'prompt_tokens') and
35
+ hasattr(usage, 'completion_tokens') and
36
+ isinstance(choices, (list, tuple))
37
+ )
38
+
39
+ def extract(self, result: Any) -> Dict[str, Any]:
40
+ """Extract trace data from OpenAI response."""
41
+ try:
42
+ return {
43
+ 'model': result.model,
44
+ 'input_tokens': result.usage.prompt_tokens,
45
+ 'output_tokens': result.usage.completion_tokens,
46
+ 'prompt': '', # Not available in response
47
+ 'response': result.choices[0].message.content
48
+ }
49
+ except (AttributeError, IndexError) as e:
50
+ logger.warning(f"Failed to extract OpenAI trace data: {e}")
51
+ return {}
52
+
53
+
54
+ class AnthropicExtractor(ResponseExtractor):
55
+ """Extractor for Anthropic response format."""
56
+
57
+ def can_extract(self, result: Any) -> bool:
58
+ """Check if result matches Anthropic format."""
59
+ usage = getattr(result, 'usage', None)
60
+ content = getattr(result, 'content', None)
61
+
62
+ return (
63
+ hasattr(result, 'model') and
64
+ hasattr(usage, 'input_tokens') and
65
+ hasattr(usage, 'output_tokens') and
66
+ isinstance(content, (list, tuple))
67
+ )
68
+
69
+ def extract(self, result: Any) -> Dict[str, Any]:
70
+ """Extract trace data from Anthropic response."""
71
+ try:
72
+ return {
73
+ 'model': result.model,
74
+ 'input_tokens': result.usage.input_tokens,
75
+ 'output_tokens': result.usage.output_tokens,
76
+ 'prompt': '', # Not available in response
77
+ 'response': result.content[0].text if result.content else ''
78
+ }
79
+ except (AttributeError, IndexError) as e:
80
+ logger.warning(f"Failed to extract Anthropic trace data: {e}")
81
+ return {}