flashlite 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.
Files changed (67) hide show
  1. flashlite-0.1.0/.gitignore +10 -0
  2. flashlite-0.1.0/.python-version +1 -0
  3. flashlite-0.1.0/.vscode/settings.json +37 -0
  4. flashlite-0.1.0/DEV.md +209 -0
  5. flashlite-0.1.0/LICENSE.md +21 -0
  6. flashlite-0.1.0/PKG-INFO +173 -0
  7. flashlite-0.1.0/QUICK_START.md +765 -0
  8. flashlite-0.1.0/README.md +153 -0
  9. flashlite-0.1.0/examples/basic_example.py +270 -0
  10. flashlite-0.1.0/examples/multi_agent_chat.py +226 -0
  11. flashlite-0.1.0/examples/stag_hunt_game.py +333 -0
  12. flashlite-0.1.0/plan.md +854 -0
  13. flashlite-0.1.0/pyproject.toml +49 -0
  14. flashlite-0.1.0/src/flashlite/__init__.py +169 -0
  15. flashlite-0.1.0/src/flashlite/cache/__init__.py +14 -0
  16. flashlite-0.1.0/src/flashlite/cache/base.py +194 -0
  17. flashlite-0.1.0/src/flashlite/cache/disk.py +285 -0
  18. flashlite-0.1.0/src/flashlite/cache/memory.py +157 -0
  19. flashlite-0.1.0/src/flashlite/client.py +671 -0
  20. flashlite-0.1.0/src/flashlite/config.py +154 -0
  21. flashlite-0.1.0/src/flashlite/conversation/__init__.py +30 -0
  22. flashlite-0.1.0/src/flashlite/conversation/context.py +319 -0
  23. flashlite-0.1.0/src/flashlite/conversation/manager.py +385 -0
  24. flashlite-0.1.0/src/flashlite/conversation/multi_agent.py +378 -0
  25. flashlite-0.1.0/src/flashlite/core/__init__.py +13 -0
  26. flashlite-0.1.0/src/flashlite/core/completion.py +145 -0
  27. flashlite-0.1.0/src/flashlite/core/messages.py +130 -0
  28. flashlite-0.1.0/src/flashlite/middleware/__init__.py +18 -0
  29. flashlite-0.1.0/src/flashlite/middleware/base.py +90 -0
  30. flashlite-0.1.0/src/flashlite/middleware/cache.py +121 -0
  31. flashlite-0.1.0/src/flashlite/middleware/logging.py +159 -0
  32. flashlite-0.1.0/src/flashlite/middleware/rate_limit.py +211 -0
  33. flashlite-0.1.0/src/flashlite/middleware/retry.py +149 -0
  34. flashlite-0.1.0/src/flashlite/observability/__init__.py +34 -0
  35. flashlite-0.1.0/src/flashlite/observability/callbacks.py +155 -0
  36. flashlite-0.1.0/src/flashlite/observability/inspect_compat.py +266 -0
  37. flashlite-0.1.0/src/flashlite/observability/logging.py +293 -0
  38. flashlite-0.1.0/src/flashlite/observability/metrics.py +221 -0
  39. flashlite-0.1.0/src/flashlite/py.typed +0 -0
  40. flashlite-0.1.0/src/flashlite/structured/__init__.py +31 -0
  41. flashlite-0.1.0/src/flashlite/structured/outputs.py +189 -0
  42. flashlite-0.1.0/src/flashlite/structured/schema.py +165 -0
  43. flashlite-0.1.0/src/flashlite/templating/__init__.py +11 -0
  44. flashlite-0.1.0/src/flashlite/templating/engine.py +217 -0
  45. flashlite-0.1.0/src/flashlite/templating/filters.py +143 -0
  46. flashlite-0.1.0/src/flashlite/templating/registry.py +165 -0
  47. flashlite-0.1.0/src/flashlite/tools/__init__.py +74 -0
  48. flashlite-0.1.0/src/flashlite/tools/definitions.py +382 -0
  49. flashlite-0.1.0/src/flashlite/tools/execution.py +353 -0
  50. flashlite-0.1.0/src/flashlite/types.py +233 -0
  51. flashlite-0.1.0/tests/__init__.py +1 -0
  52. flashlite-0.1.0/tests/conftest.py +47 -0
  53. flashlite-0.1.0/tests/test_cache.py +362 -0
  54. flashlite-0.1.0/tests/test_cache_integration.py +218 -0
  55. flashlite-0.1.0/tests/test_client.py +315 -0
  56. flashlite-0.1.0/tests/test_config.py +117 -0
  57. flashlite-0.1.0/tests/test_conversation.py +385 -0
  58. flashlite-0.1.0/tests/test_integration.py +242 -0
  59. flashlite-0.1.0/tests/test_messages.py +154 -0
  60. flashlite-0.1.0/tests/test_middleware.py +325 -0
  61. flashlite-0.1.0/tests/test_multi_agent.py +381 -0
  62. flashlite-0.1.0/tests/test_observability.py +368 -0
  63. flashlite-0.1.0/tests/test_structured.py +368 -0
  64. flashlite-0.1.0/tests/test_templating.py +177 -0
  65. flashlite-0.1.0/tests/test_tools.py +520 -0
  66. flashlite-0.1.0/tests/test_types.py +241 -0
  67. flashlite-0.1.0/uv.lock +1579 -0
@@ -0,0 +1,10 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,37 @@
1
+ {
2
+ "files.exclude": {
3
+ "**/__pycache__": true,
4
+ "**/.cache": true,
5
+ "**/.pytest_cache": true,
6
+ "**/node_modules": true,
7
+ "**/.git": true,
8
+ "**/.DS_Store": true,
9
+ "**/.ruff_cache": true,
10
+ "**/.venv": true,
11
+ "**/*.egg-info": true,
12
+ "**/.mypy_cache": true,
13
+ },
14
+ "search.exclude": {
15
+ "**/__pycache__": true,
16
+ "**/.cache": true,
17
+ "**/.pytest_cache": true,
18
+ "**/node_modules": true,
19
+ "**/.git": true,
20
+ "**/.ruff_cache": true,
21
+ "**/.venv": true,
22
+ "**/*.egg-info": true,
23
+ "**/.mypy_cache": true,
24
+ },
25
+ "[python]": {
26
+ "editor.formatOnSave": true,
27
+ "editor.defaultFormatter": "charliermarsh.ruff",
28
+ "editor.codeActionsOnSave": {
29
+ "source.fixAll.ruff": "always",
30
+ "source.organizeImports.ruff": "always"
31
+ }
32
+ },
33
+ "ruff.path": [
34
+ "uvx",
35
+ "ruff"
36
+ ]
37
+ }
flashlite-0.1.0/DEV.md ADDED
@@ -0,0 +1,209 @@
1
+ # Flashlite Development Guide
2
+
3
+ ## Prerequisites
4
+
5
+ - Python 3.13+
6
+ - [uv](https://docs.astral.sh/uv/) package manager
7
+
8
+ ## Setup
9
+
10
+ ```bash
11
+ # Clone the repository
12
+ git clone https://github.com/yourusername/flashlite.git
13
+ cd flashlite
14
+
15
+ # Install dependencies (creates virtualenv automatically)
16
+ uv sync --all-extras
17
+
18
+ # Activate the virtual environment (optional, uv run handles this)
19
+ source .venv/bin/activate
20
+ ```
21
+
22
+ ## Common Commands
23
+
24
+ ### Running Tests
25
+
26
+ ```bash
27
+ # Run all tests
28
+ uv run pytest
29
+
30
+ # Run with verbose output
31
+ uv run pytest -v
32
+
33
+ # Run specific test file
34
+ uv run pytest tests/test_client.py
35
+
36
+ # Run specific test class or function
37
+ uv run pytest tests/test_client.py::TestFlashliteClient::test_complete_with_messages
38
+
39
+ # Run with coverage
40
+ uv run pytest --cov=flashlite --cov-report=html
41
+
42
+ # Run tests matching a pattern
43
+ uv run pytest -k "cache"
44
+ ```
45
+
46
+ ### Linting & Formatting
47
+
48
+ ```bash
49
+ # Run ruff linter
50
+ uv run ruff check src/
51
+
52
+ # Auto-fix linting issues
53
+ uv run ruff check src/ --fix
54
+
55
+ # Format code
56
+ uv run ruff format src/
57
+
58
+ # Check formatting without changing files
59
+ uv run ruff format src/ --check
60
+ ```
61
+
62
+ ### Type Checking
63
+
64
+ ```bash
65
+ # Run mypy
66
+ uv run mypy src/flashlite
67
+ ```
68
+
69
+ ### Running All Checks
70
+
71
+ ```bash
72
+ # Run linting, type checking, and tests
73
+ uv run ruff check src/ && uv run mypy src/flashlite && uv run pytest
74
+ ```
75
+
76
+ ## Project Structure
77
+
78
+ ```
79
+ flashlite/
80
+ ├── src/flashlite/ # Main package
81
+ │ ├── __init__.py # Public API exports
82
+ │ ├── client.py # Main Flashlite client
83
+ │ ├── config.py # Configuration and .env loading
84
+ │ ├── types.py # Type definitions
85
+ │ ├── core/ # Core completion logic
86
+ │ ├── middleware/ # Request/response middleware
87
+ │ ├── templating/ # Jinja templating
88
+ │ ├── cache/ # Caching backends
89
+ │ ├── observability/ # Logging, metrics, Inspect compat
90
+ │ ├── structured/ # Pydantic structured outputs
91
+ │ ├── conversation/ # Multi-turn conversations, context & multi-agent
92
+ │ │ ├── manager.py # Single-agent Conversation class
93
+ │ │ ├── context.py # Context window management
94
+ │ │ └── multi_agent.py # MultiAgentChat for agent-to-agent conversations
95
+ │ └── tools/ # Tool/function calling helpers
96
+ ├── tests/ # Test suite
97
+ ├── examples/ # Example scripts
98
+ │ ├── basic_example.py # Basic features demo
99
+ │ └── multi_agent_chat.py # Multi-agent conversation example
100
+ ├── pyproject.toml # Project configuration
101
+ ├── plan.md # Implementation plan
102
+ └── README.md # User documentation
103
+ ```
104
+
105
+ ## Running Examples
106
+
107
+ ```bash
108
+ # Run basic example
109
+ uv run python examples/basic_example.py
110
+
111
+ # Run multi-agent chat example
112
+ uv run python examples/multi_agent_chat.py
113
+ ```
114
+
115
+ ## Testing Without API Keys
116
+
117
+ Flashlite tests use litellm's `mock_response` feature to avoid hitting real APIs:
118
+
119
+ ```python
120
+ async def test_example():
121
+ client = Flashlite(default_model="gpt-4o")
122
+
123
+ # mock_response returns a fake response without API calls
124
+ response = await client.complete(
125
+ messages="Hello",
126
+ mock_response="This is a mocked response",
127
+ )
128
+
129
+ assert response.content == "This is a mocked response"
130
+ ```
131
+
132
+ ## Adding New Features
133
+
134
+ 1. **Create a branch** for your feature
135
+ 2. **Write tests first** in the appropriate test file
136
+ 3. **Implement the feature** in the relevant module
137
+ 4. **Run linting and tests** to ensure quality
138
+ 5. **Update documentation** if needed
139
+
140
+ ### Middleware Pattern
141
+
142
+ New features that process requests/responses should use the middleware pattern:
143
+
144
+ ```python
145
+ from flashlite.middleware.base import Middleware
146
+ from flashlite.types import CompletionRequest, CompletionResponse
147
+
148
+ class MyMiddleware(Middleware):
149
+ async def __call__(
150
+ self,
151
+ request: CompletionRequest,
152
+ next_handler: Callable[[CompletionRequest], Awaitable[CompletionResponse]],
153
+ ) -> CompletionResponse:
154
+ # Pre-processing
155
+ print(f"Processing request for {request.model}")
156
+
157
+ # Call next middleware/handler
158
+ response = await next_handler(request)
159
+
160
+ # Post-processing
161
+ print(f"Got response with {response.usage.total_tokens} tokens")
162
+
163
+ return response
164
+ ```
165
+
166
+ ## Environment Variables
167
+
168
+ Create a `.env` file for local development:
169
+
170
+ ```bash
171
+ # API Keys
172
+ OPENAI_API_KEY=sk-...
173
+ ANTHROPIC_API_KEY=sk-ant-...
174
+
175
+ # Flashlite defaults (optional)
176
+ FLASHLITE_DEFAULT_MODEL=gpt-4o
177
+ FLASHLITE_LOG_LEVEL=DEBUG
178
+ ```
179
+
180
+ ## Debugging
181
+
182
+ ### Enable Debug Logging
183
+
184
+ ```python
185
+ import logging
186
+ logging.basicConfig(level=logging.DEBUG)
187
+
188
+ client = Flashlite(log_level="DEBUG", log_requests=True)
189
+ ```
190
+
191
+ ### Inspect Middleware Chain
192
+
193
+ ```python
194
+ client = Flashlite(...)
195
+ print(f"Middleware stack: {client._middleware}")
196
+ ```
197
+
198
+ ## Release Process
199
+
200
+ 1. Update version in `src/flashlite/__init__.py`
201
+ 2. Update `pyproject.toml` version
202
+ 3. Run full test suite
203
+ 4. Create git tag
204
+ 5. Build and publish:
205
+
206
+ ```bash
207
+ uv build
208
+ uv publish
209
+ ```
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Niall Dalton
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.
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: flashlite
3
+ Version: 0.1.0
4
+ Summary: Batteries-included wrapper for litellm with rate limiting, retries, templating, and more
5
+ Author-email: ndalton12 <niall.dalton12@gmail.com>
6
+ License-File: LICENSE.md
7
+ Requires-Python: >=3.13
8
+ Requires-Dist: jinja2>=3.1.0
9
+ Requires-Dist: litellm>=1.55.0
10
+ Requires-Dist: pydantic>=2.0
11
+ Requires-Dist: python-dotenv>=1.0.0
12
+ Requires-Dist: tenacity>=8.0.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
15
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
16
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
17
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
18
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Flashlite
22
+
23
+ A batteries-included wrapper for [litellm](https://github.com/BerriAI/litellm) designed for high-volume prompting workloads like evals, agentic loops, and social simulations.
24
+
25
+ ## Features
26
+
27
+ - **Rate Limiting** - Token bucket algorithm for RPM and TPM limits
28
+ - **Retries** - Exponential backoff with jitter via tenacity
29
+ - **Jinja Templating** - Prompt templates with custom filters
30
+ - **Caching** - In-memory LRU and SQLite disk caching
31
+ - **Structured Outputs** - Native Pydantic model parsing without instructor
32
+ - **Tool/Function Calling** - `@tool` decorator and execution loops
33
+ - **Multi-Turn Conversations** - Conversation management with branching
34
+ - **Cost Tracking** - Token counting and budget limits
35
+ - **Observability** - Structured logging and Inspect framework integration
36
+ - **Async-First** - Native async with sync wrappers
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install flashlite
42
+ # or with uv
43
+ uv add flashlite
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ```python
49
+ from flashlite import Flashlite
50
+
51
+ # Create client (loads .env automatically)
52
+ client = Flashlite(default_model="gpt-4o")
53
+
54
+ # Simple completion
55
+ response = await client.complete(
56
+ messages="What is the capital of France?"
57
+ )
58
+ print(response.content)
59
+
60
+ # Sync version
61
+ response = client.complete_sync(messages="Hello!")
62
+ ```
63
+
64
+ ### Structured Outputs
65
+
66
+ ```python
67
+ from pydantic import BaseModel, Field
68
+ from flashlite import Flashlite
69
+
70
+ class Sentiment(BaseModel):
71
+ label: str = Field(description="positive, negative, or neutral")
72
+ confidence: float = Field(ge=0, le=1)
73
+
74
+ client = Flashlite(default_model="gpt-4o")
75
+
76
+ result: Sentiment = await client.complete(
77
+ messages="Analyze: 'I love this product!'",
78
+ response_model=Sentiment,
79
+ )
80
+ print(f"{result.label} ({result.confidence:.0%})")
81
+ ```
82
+
83
+ ### Tool/Function Calling
84
+
85
+ ```python
86
+ from flashlite import Flashlite, tool, run_tool_loop
87
+
88
+ @tool()
89
+ def get_weather(location: str) -> str:
90
+ """Get weather for a location."""
91
+ return f"Weather in {location}: 72°F, sunny"
92
+
93
+ client = Flashlite(default_model="gpt-4o")
94
+
95
+ result = await run_tool_loop(
96
+ client=client,
97
+ messages=[{"role": "user", "content": "What's the weather in NYC?"}],
98
+ tools=[get_weather],
99
+ )
100
+ print(result.content)
101
+ ```
102
+
103
+ ### Parallel Processing
104
+
105
+ ```python
106
+ # Process many requests with concurrency control
107
+ responses = await client.complete_many(
108
+ requests=[
109
+ {"messages": f"Summarize: {doc}"}
110
+ for doc in documents
111
+ ],
112
+ max_concurrency=10,
113
+ )
114
+ ```
115
+
116
+ ### Caching
117
+
118
+ ```python
119
+ from flashlite import Flashlite, MemoryCache, DiskCache
120
+
121
+ # In-memory caching
122
+ client = Flashlite(
123
+ cache=MemoryCache(max_size=1000),
124
+ default_model="gpt-4o",
125
+ )
126
+
127
+ # Or persistent disk cache
128
+ client = Flashlite(
129
+ cache=DiskCache("./cache.db"),
130
+ default_model="gpt-4o",
131
+ )
132
+ ```
133
+
134
+ ### Reasoning Models
135
+
136
+ ```python
137
+ from flashlite import Flashlite, thinking_enabled
138
+
139
+ client = Flashlite()
140
+
141
+ # OpenAI o1/o3
142
+ response = await client.complete(
143
+ model="o3",
144
+ messages="Solve this complex problem...",
145
+ reasoning_effort="high",
146
+ )
147
+
148
+ # Anthropic Claude extended thinking
149
+ response = await client.complete(
150
+ model="anthropic/claude-sonnet-4-5-20250929",
151
+ messages="Complex reasoning task...",
152
+ thinking=thinking_enabled(10000),
153
+ )
154
+ ```
155
+
156
+ ## Documentation
157
+
158
+ - [Quick Start Guide](QUICK_START.md) - Detailed examples for all features
159
+ - [Development Guide](DEV.md) - Setup and contributing
160
+ - [Implementation Plan](plan.md) - Architecture and roadmap
161
+
162
+ ## Requirements
163
+
164
+ - Python 3.13+
165
+ - litellm
166
+ - pydantic>=2.0
167
+ - jinja2
168
+ - tenacity
169
+ - python-dotenv
170
+
171
+ ## License
172
+
173
+ MIT