forecost 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 (50) hide show
  1. forecost-0.1.0/.forecost.toml.example +5 -0
  2. forecost-0.1.0/.github/FUNDING.yml +1 -0
  3. forecost-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +46 -0
  4. forecost-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +25 -0
  5. forecost-0.1.0/.github/workflows/ci.yml +52 -0
  6. forecost-0.1.0/.github/workflows/release.yml +51 -0
  7. forecost-0.1.0/.gitignore +55 -0
  8. forecost-0.1.0/CHANGELOG.md +33 -0
  9. forecost-0.1.0/CLAUDE.md +46 -0
  10. forecost-0.1.0/CONTRIBUTING.md +39 -0
  11. forecost-0.1.0/LICENSE +21 -0
  12. forecost-0.1.0/PKG-INFO +249 -0
  13. forecost-0.1.0/README.md +205 -0
  14. forecost-0.1.0/demo.tape +24 -0
  15. forecost-0.1.0/forecost/__init__.py +68 -0
  16. forecost-0.1.0/forecost/cli.py +32 -0
  17. forecost-0.1.0/forecost/commands/__init__.py +0 -0
  18. forecost-0.1.0/forecost/commands/demo_cmd.py +117 -0
  19. forecost-0.1.0/forecost/commands/export_cmd.py +50 -0
  20. forecost-0.1.0/forecost/commands/forecast_cmd.py +273 -0
  21. forecost-0.1.0/forecost/commands/init_cmd.py +120 -0
  22. forecost-0.1.0/forecost/commands/optimize_cmd.py +107 -0
  23. forecost-0.1.0/forecost/commands/reset_cmd.py +47 -0
  24. forecost-0.1.0/forecost/commands/serve_cmd.py +114 -0
  25. forecost-0.1.0/forecost/commands/status_cmd.py +53 -0
  26. forecost-0.1.0/forecost/commands/track_cmd.py +61 -0
  27. forecost-0.1.0/forecost/commands/watch_cmd.py +86 -0
  28. forecost-0.1.0/forecost/db.py +339 -0
  29. forecost-0.1.0/forecost/forecaster.py +311 -0
  30. forecost-0.1.0/forecost/interceptor.py +231 -0
  31. forecost-0.1.0/forecost/pricing.py +166 -0
  32. forecost-0.1.0/forecost/py.typed +0 -0
  33. forecost-0.1.0/forecost/scope.py +231 -0
  34. forecost-0.1.0/forecost/tracker.py +226 -0
  35. forecost-0.1.0/forecost/tui.py +149 -0
  36. forecost-0.1.0/pyproject.toml +57 -0
  37. forecost-0.1.0/scripts/test_real_sdk.py +108 -0
  38. forecost-0.1.0/tests/__init__.py +0 -0
  39. forecost-0.1.0/tests/benchmarks/__init__.py +0 -0
  40. forecost-0.1.0/tests/benchmarks/test_forecast_accuracy.py +220 -0
  41. forecost-0.1.0/tests/conftest.py +10 -0
  42. forecost-0.1.0/tests/test_cli.py +36 -0
  43. forecost-0.1.0/tests/test_commands.py +218 -0
  44. forecost-0.1.0/tests/test_db.py +121 -0
  45. forecost-0.1.0/tests/test_forecaster.py +216 -0
  46. forecost-0.1.0/tests/test_interceptor.py +39 -0
  47. forecost-0.1.0/tests/test_pricing.py +47 -0
  48. forecost-0.1.0/tests/test_production.py +217 -0
  49. forecost-0.1.0/tests/test_sdk_compat.py +177 -0
  50. forecost-0.1.0/tests/test_tracker.py +35 -0
@@ -0,0 +1,5 @@
1
+ # This file is created by `forecost init`
2
+ # Add .forecost.toml to your .gitignore
3
+ project_name = "your-project"
4
+ path = "."
5
+ created_at = "2026-01-01T00:00:00+00:00"
@@ -0,0 +1 @@
1
+ github: ArivunidhiA
@@ -0,0 +1,46 @@
1
+ name: Bug Report
2
+ description: Report a bug in forecost
3
+ labels: [bug]
4
+ body:
5
+ - type: input
6
+ id: version
7
+ attributes:
8
+ label: forecost version
9
+ placeholder: "0.1.0"
10
+ validations:
11
+ required: true
12
+ - type: input
13
+ id: python-version
14
+ attributes:
15
+ label: Python version
16
+ placeholder: "3.12"
17
+ validations:
18
+ required: true
19
+ - type: input
20
+ id: os
21
+ attributes:
22
+ label: Operating System
23
+ placeholder: "macOS 15, Ubuntu 24.04, Windows 11"
24
+ validations:
25
+ required: true
26
+ - type: textarea
27
+ id: description
28
+ attributes:
29
+ label: What happened?
30
+ description: Describe the bug clearly.
31
+ validations:
32
+ required: true
33
+ - type: textarea
34
+ id: steps
35
+ attributes:
36
+ label: Steps to reproduce
37
+ description: How can we reproduce the issue?
38
+ validations:
39
+ required: true
40
+ - type: textarea
41
+ id: expected
42
+ attributes:
43
+ label: Expected behavior
44
+ description: What did you expect to happen?
45
+ validations:
46
+ required: true
@@ -0,0 +1,25 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature for forecost
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: Description
9
+ description: What feature would you like?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: use-case
14
+ attributes:
15
+ label: Use case
16
+ description: Why do you need this feature?
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: solution
21
+ attributes:
22
+ label: Proposed solution
23
+ description: How would you implement this?
24
+ validations:
25
+ required: false
@@ -0,0 +1,52 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+
8
+ concurrency:
9
+ group: ci-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ cache: pip
21
+ - run: pip install -e ".[dev]"
22
+ - run: ruff check forecost/ tests/
23
+ - run: ruff format --check forecost/ tests/
24
+
25
+ test:
26
+ runs-on: ${{ matrix.os }}
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ python-version: ["3.10", "3.11", "3.12"]
31
+ os: [ubuntu-latest, macos-latest]
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - uses: actions/setup-python@v5
35
+ with:
36
+ python-version: ${{ matrix.python-version }}
37
+ cache: pip
38
+ - run: pip install -e ".[dev,forecast]"
39
+ - run: pytest tests/ -v --tb=short -x
40
+
41
+ smoke:
42
+ runs-on: ubuntu-latest
43
+ needs: [lint, test]
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: actions/setup-python@v5
47
+ with:
48
+ python-version: "3.12"
49
+ - run: pip install .
50
+ - run: forecost --version
51
+ - run: forecost --help
52
+ - run: forecost demo
@@ -0,0 +1,51 @@
1
+ name: Release to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ jobs:
7
+ build:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+ with:
12
+ fetch-depth: 0
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.12"
16
+ - run: pip install build
17
+ - run: python -m build
18
+ - uses: actions/upload-artifact@v4
19
+ with:
20
+ name: dist
21
+ path: dist/
22
+
23
+ test-install:
24
+ needs: build
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/download-artifact@v4
28
+ with:
29
+ name: dist
30
+ path: dist/
31
+ - uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.12"
34
+ - run: pip install dist/*.whl
35
+ - run: forecost --version
36
+ - run: forecost demo
37
+
38
+ publish:
39
+ needs: [build, test-install]
40
+ runs-on: ubuntu-latest
41
+ environment:
42
+ name: pypi
43
+ url: https://pypi.org/p/forecost
44
+ permissions:
45
+ id-token: write
46
+ steps:
47
+ - uses: actions/download-artifact@v4
48
+ with:
49
+ name: dist
50
+ path: dist/
51
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,55 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg-info/
7
+ *.egg
8
+ dist/
9
+ build/
10
+ .eggs/
11
+
12
+ # Virtual environments
13
+ venv/
14
+ .venv/
15
+ env/
16
+
17
+ # Environment variables
18
+ .env
19
+ *.env.local
20
+
21
+ # Databases
22
+ *.db
23
+ *.sqlite3
24
+
25
+ # IDE
26
+ .vscode/
27
+ .idea/
28
+ *.swp
29
+ *.swo
30
+ *~
31
+
32
+ # OS
33
+ .DS_Store
34
+ Thumbs.db
35
+
36
+ # Node.js / Frontend
37
+ node_modules/
38
+ .next/
39
+ out/
40
+
41
+ # Test
42
+ .pytest_cache/
43
+ htmlcov/
44
+ .coverage
45
+ coverage.xml
46
+
47
+ # Logs
48
+ *.log
49
+
50
+ # Cursor
51
+ .cursor/
52
+
53
+ # forecost
54
+ .forecost.toml
55
+ .forecost/
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/).
6
+
7
+ ## [0.1.0] - 2026-03-12
8
+
9
+ ### Changed
10
+ - **Branding:** PyPI package, CLI, and Python import are **`forecost`**. Project config is **`.forecost.toml`**; local data lives under **`~/.forecost/`**. Disable tracking with **`FORECOST_DISABLED=1`** (replaces older env var names).
11
+
12
+ ### Added
13
+ - `forecost init` -- Initialize project with heuristic or LLM-powered scope analysis
14
+ - `forecost forecast` -- Adaptive exponential smoothing cost forecast with Rich output
15
+ - `forecost status` -- One-line project status
16
+ - `forecost track` -- View recent tracked LLM calls
17
+ - `forecost serve` -- Local HTTP API server
18
+ - `forecost demo` -- See forecost in action with sample data
19
+ - `forecost watch` -- Live cost dashboard in terminal
20
+ - `forecost optimize` -- Model optimization suggestions
21
+ - `forecost reset` -- Reset project baseline or full data
22
+ - `auto_track()` -- Zero-code-change cost tracking via httpx interception
23
+ - `log_call()` -- Manual cost logging
24
+ - `log_stream_usage()` -- Streaming response cost logging
25
+ - `@track_cost` decorator for function-level tracking
26
+ - `FORECOST_DISABLED` environment variable to disable tracking
27
+ - `forecost.disable()` function
28
+ - Support for 90+ models across OpenAI, Anthropic, Google, Mistral, DeepSeek, xAI, Meta, Cohere
29
+ - Self-correcting pricing via ratio-based forecasting
30
+ - Forecast stability metric (replaces misleading MAPE)
31
+ - Budget alerts and CI exit codes (`--exit-code`)
32
+ - Optional Textual TUI dashboard (`pip install forecost[tui]`)
33
+ - PEP 561 py.typed marker for type checking support
@@ -0,0 +1,46 @@
1
+ # forecost Development Guide
2
+
3
+ ## What This Project Is
4
+ forecost is a local-first Python CLI tool that forecasts LLM API costs.
5
+ It uses adaptive exponential smoothing (upgrading to a 3-model ensemble)
6
+ on daily spend data to predict total project cost.
7
+
8
+ ## Architecture Rules
9
+ - All source code lives in forecost/ (flat layout, not src/)
10
+ - CLI commands are in forecost/commands/ — each is a thin wrapper calling core logic
11
+ - Core modules: db.py (SQLite), pricing.py (static prices), forecaster.py (ensemble),
12
+ interceptor.py (httpx patching), tracker.py (public API), scope.py (heuristic analyzer)
13
+ - Tests live in tests/ and tests/benchmarks/
14
+ - pyproject.toml uses hatchling build backend
15
+
16
+ ## Iron Rules (Never Violate These)
17
+ 1. The interceptor must NEVER break the host application's HTTP requests.
18
+ All tracking logic is wrapped in try/except. Real errors propagate, tracking errors are swallowed.
19
+ 2. calculate_forecast(save=False) is the default. Only the explicit `forecast` command saves.
20
+ Status, serve, and JSON output do NOT save forecast rows.
21
+ 3. No network calls for pricing data. All prices are hardcoded in FALLBACK_PRICING dict.
22
+ 4. The WriteQueue worker thread has its OWN SQLite connection. Never share connections across threads.
23
+ 5. .forecost.toml uses relative paths (path = "."). Never write absolute paths to config files.
24
+
25
+ ## Testing Rules
26
+ - Run pytest tests/ -v after every change
27
+ - The forecaster is the most important module — test accuracy with synthetic data
28
+ - The interceptor is the most dangerous module — test that it never breaks httpx
29
+ - Mock all HTTP calls in tests. Never make real API calls.
30
+ - Benchmarks in tests/benchmarks/ can be slower but must pass
31
+
32
+ ## What NOT To Do
33
+ - Don't add a web dashboard or frontend
34
+ - Don't add database migrations (schema-less metadata JSON column handles extensibility)
35
+ - Don't add authentication or multi-user support
36
+ - Don't add real-time pricing fetches from the internet
37
+ - Don't add heavy ML dependencies (statsmodels is the ceiling)
38
+ - Don't use except Exception: pass — always log errors to ~/.forecost/error.log
39
+
40
+ ## Key Commands
41
+ pip install -e ".[dev,forecast]" # Install for development
42
+ pytest tests/ -v # Run all tests
43
+ pytest tests/benchmarks/ -v # Run accuracy benchmarks
44
+ ruff check forecost/ tests/ # Lint
45
+ forecost demo # See it working with sample data
46
+ python -m build # Build for PyPI
@@ -0,0 +1,39 @@
1
+ # Contributing to forecost
2
+
3
+ Thanks for your interest in contributing to forecost.
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/ArivunidhiA/forecost.git
9
+ cd forecost
10
+ python -m venv .venv
11
+ source .venv/bin/activate
12
+ pip install -e ".[dev]"
13
+ ```
14
+
15
+ ## Running Tests
16
+
17
+ ```bash
18
+ pytest tests/ -v
19
+ ```
20
+
21
+ ## Code Style
22
+
23
+ We use ruff for linting and formatting:
24
+
25
+ ```bash
26
+ ruff check forecost/ tests/
27
+ ruff format forecost/ tests/
28
+ ```
29
+
30
+ ## Pull Request Process
31
+
32
+ 1. Fork the repo and create a feature branch
33
+ 2. Make your changes with tests
34
+ 3. Ensure `ruff check` and `pytest` pass
35
+ 4. Submit a PR against `main`
36
+
37
+ ## Reporting Issues
38
+
39
+ Use the GitHub issue templates for bugs and feature requests.
forecost-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arivunidhi A
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,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: forecost
3
+ Version: 0.1.0
4
+ Summary: Know exactly what your AI project will cost. Local-first LLM cost forecasting that learns from your usage.
5
+ Project-URL: Homepage, https://github.com/ArivunidhiA/forecost
6
+ Project-URL: Issues, https://github.com/ArivunidhiA/forecost/issues
7
+ Author: Forecost contributors
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: anthropic,cli,cost,forecast,llm,openai
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: click>=8.0
19
+ Requires-Dist: httpx>=0.25.0
20
+ Requires-Dist: rich>=13.0
21
+ Requires-Dist: tomli>=2.0.0; python_version < '3.11'
22
+ Provides-Extra: all
23
+ Requires-Dist: litellm>=1.0; extra == 'all'
24
+ Requires-Dist: numpy>=1.24; extra == 'all'
25
+ Requires-Dist: plotext>=5.0; extra == 'all'
26
+ Requires-Dist: statsmodels>=0.14; extra == 'all'
27
+ Requires-Dist: textual>=0.50; extra == 'all'
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy; extra == 'dev'
30
+ Requires-Dist: numpy>=1.24; extra == 'dev'
31
+ Requires-Dist: pytest-cov; extra == 'dev'
32
+ Requires-Dist: pytest>=7.0; extra == 'dev'
33
+ Requires-Dist: ruff; extra == 'dev'
34
+ Requires-Dist: statsmodels>=0.14; extra == 'dev'
35
+ Provides-Extra: forecast
36
+ Requires-Dist: numpy>=1.24; extra == 'forecast'
37
+ Requires-Dist: statsmodels>=0.14; extra == 'forecast'
38
+ Provides-Extra: llm
39
+ Requires-Dist: litellm>=1.0; extra == 'llm'
40
+ Provides-Extra: tui
41
+ Requires-Dist: plotext>=5.0; extra == 'tui'
42
+ Requires-Dist: textual>=0.50; extra == 'tui'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # forecost
46
+
47
+ **Know what your AI project will cost. Before you build it.**
48
+
49
+ [![PyPI version](https://img.shields.io/pypi/v/forecost.svg)](https://pypi.org/project/forecost/)
50
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
52
+
53
+ Python 3.10+ required. forecost is in Alpha: APIs may change and some features are experimental.
54
+
55
+ See `forecost demo` for a live preview.
56
+
57
+ ## The Problem
58
+
59
+ LLM API costs are unpredictable. You prototype with GPT-4, ship to production, and the first month's bill arrives as a surprise. Most teams have no way to forecast spend until it's too late. forecost fixes this by learning from your actual usage and giving you accurate cost projections before you scale.
60
+
61
+ ## Quick Start
62
+
63
+ Full walkthrough from install to forecast:
64
+
65
+ ```bash
66
+ pip install forecost
67
+ cd your-project
68
+ forecost init
69
+ ```
70
+
71
+ Add to your app's entry point (before any LLM calls):
72
+
73
+ ```python
74
+ import forecost
75
+ forecost.auto_track()
76
+ ```
77
+
78
+ Call `auto_track()` early, before any httpx usage. If your app imports httpx before forecost, the interceptor may not attach correctly.
79
+
80
+ Run your app as usual. After building usage for a few days:
81
+
82
+ ```bash
83
+ forecost forecast
84
+ ```
85
+
86
+ ## See It in Action
87
+
88
+ `forecost demo` runs a forecast with sample data and no setup. Use it to see the full output before tracking your own project.
89
+
90
+ ## Auto-Tracking
91
+
92
+ Non-streaming calls are tracked automatically. No decorators, no manual logging.
93
+
94
+ **Streaming limitation:** forecost cannot intercept streaming responses automatically. You must call `log_stream_usage` after consuming the stream. Pass the accumulated response dict containing a `usage` key (and optionally `model` for identification):
95
+
96
+ ```python
97
+ import forecost
98
+ forecost.auto_track()
99
+
100
+ # Example: OpenAI streaming
101
+ response = client.chat.completions.create(model="gpt-4", messages=[...], stream=True)
102
+ accumulated = {"usage": {"prompt_tokens": 0, "completion_tokens": 0}, "model": "gpt-4"}
103
+ for chunk in response:
104
+ if chunk.usage:
105
+ accumulated["usage"] = {"prompt_tokens": chunk.usage.prompt_tokens,
106
+ "completion_tokens": chunk.usage.completion_tokens}
107
+ if chunk.model:
108
+ accumulated["model"] = chunk.model
109
+ forecost.log_stream_usage(accumulated)
110
+ ```
111
+
112
+ For Anthropic, use `input_tokens` and `output_tokens` instead of `prompt_tokens` and `completion_tokens`.
113
+
114
+ ## Manual Tracking
115
+
116
+ For fine-grained control, use the `@track_cost` decorator or `log_call`:
117
+
118
+ ```python
119
+ import forecost
120
+
121
+ @forecost.track_cost(provider="openai")
122
+ def call_gpt(prompt: str):
123
+ return openai.chat.completions.create(model="gpt-4", messages=[{"role": "user", "content": prompt}])
124
+
125
+ # Or log calls manually
126
+ forecost.log_call(model="gpt-4", tokens_in=500, tokens_out=200, provider="openai")
127
+ ```
128
+
129
+ ## Commands
130
+
131
+ | Command | Description |
132
+ |---------|-------------|
133
+ | `forecost init` | Initialize project and create `.forecost.toml` config |
134
+ | `forecost init --budget X` | Set a budget cap in USD |
135
+ | `forecost forecast` | Show cost forecast in terminal |
136
+ | `forecost forecast --output markdown` | Output forecast as Markdown |
137
+ | `forecost forecast --output csv` | Output forecast as CSV |
138
+ | `forecost forecast --tui` | Interactive TUI dashboard (requires `pip install forecost[tui]`) |
139
+ | `forecost forecast --json` | JSON output for CI/scripts |
140
+ | `forecost forecast --brief` | One-line summary (same format as `status`) |
141
+ | `forecost forecast --exit-code` | Exit 1 if projected over budget, 2 if actual over budget (for CI) |
142
+ | `forecost status` | One-line summary: spend, projected total, day count, drift status |
143
+ | `forecost track` | View recent tracked LLM calls |
144
+ | `forecost watch` | Live cost dashboard; updates as your app makes calls |
145
+ | `forecost export --format csv` | Export usage data as CSV |
146
+ | `forecost export --format json` | Export usage data as JSON |
147
+ | `forecost demo` | Run forecast with sample data, no setup needed |
148
+ | `forecost optimize` | Suggest cost optimizations based on usage |
149
+ | `forecost reset` | Reset the current project (optionally keep usage logs) |
150
+ | `forecost serve` | Run local API server for programmatic access |
151
+
152
+ `status` and `forecast --brief` both show the same one-line summary. Use `status` when you only need a quick check; use `forecast --brief` when you want that format in a script or CI pipeline.
153
+
154
+ ## Budget Enforcement
155
+
156
+ Set a budget at init with `--budget`:
157
+
158
+ ```bash
159
+ forecost init --budget 100
160
+ ```
161
+
162
+ Use `--exit-code` on forecast to fail CI when over budget:
163
+
164
+ ```yaml
165
+ - name: Check LLM Budget
166
+ run: |
167
+ pip install forecost
168
+ forecost forecast --exit-code
169
+ ```
170
+
171
+ Exit codes: 0 = on track, 1 = projected over budget, 2 = actual spend over budget.
172
+
173
+ ## Disabling in Tests
174
+
175
+ ```bash
176
+ FORECOST_DISABLED=1 pytest
177
+ ```
178
+
179
+ Or in code:
180
+
181
+ ```python
182
+ forecost.disable()
183
+ ```
184
+
185
+ ## Forecasting Accuracy
186
+
187
+ forecost uses an ensemble of three statistical forecasting methods (Simple Exponential Smoothing, Damped Trend, and Linear Regression) inspired by the M4 Forecasting Competition, where simple combinations beat complex ML models across 100,000 time series.
188
+
189
+ | Metric | What it means | Typical result |
190
+ |--------|---------------|----------------|
191
+ | MASE | Are we beating a naive guess? | < 1.0 after 5 days |
192
+ | MAE | How many dollars could we be off? | Decreases as data grows |
193
+ | 80% interval | Will the real cost land here? | ~80% of the time |
194
+ | 95% interval | Conservative budget range | ~95% of the time |
195
+
196
+ Install the ensemble engine for best results: `pip install forecost[forecast]`
197
+
198
+ The base install uses a simpler exponential moving average that works without additional dependencies.
199
+
200
+ ## Why forecost?
201
+
202
+ | Feature | forecost | LiteLLM | Helicone | LangSmith |
203
+ |---------|--------|---------|----------|-----------|
204
+ | Cost tracking | Yes | Yes | Yes | Yes |
205
+ | Cost forecasting | Yes | No | No | No |
206
+ | Prediction intervals | Yes | No | No | No |
207
+ | Zero infrastructure | Yes | No (proxy) | No (cloud) | No (cloud) |
208
+ | Zero overhead on requests | Yes (post-response) | No (proxy latency) | No (proxy latency) | No (SDK wrapper) |
209
+ | Local-only / private | Yes | Partial | No | No |
210
+ | pip install, 2 lines | Yes | SDK wrapper | Proxy setup | SDK setup |
211
+ | Free forever | Yes | Freemium | Freemium | $39/seat/mo |
212
+
213
+ Minimal footprint: 3 runtime dependencies (click, rich, httpx), under 3MB.
214
+
215
+ ## Data Storage
216
+
217
+ - **Usage and forecasts:** `~/.forecost/costs.db` (SQLite). All projects share this database.
218
+ - **Project config:** `.forecost.toml` in your project root. Contains project name, baseline days, and optional budget.
219
+
220
+ ## Glossary
221
+
222
+ | Term | Meaning |
223
+ |------|---------|
224
+ | **Confidence levels** | How reliable the forecast is based on data volume: low (0 days), medium-low (1-3), medium (4-7), high (8-14), very-high (15+). More usage data yields higher confidence. |
225
+ | **Drift status** | Whether spend is trending above or below the baseline: `on_track`, `over_budget`, or `under_budget`. Based on recent daily burn ratios. |
226
+ | **MASE** | Mean Absolute Scaled Error. Compares forecast accuracy to a naive "yesterday = tomorrow" guess. MASE < 1.0 means the forecast beats the naive baseline. |
227
+ | **Stability** | How much the forecast changes between runs: `converged` (< 5% change), `stabilizing` (5-15%), or `adjusting` (> 15%). |
228
+ | **Prediction intervals** | 80% and 95% ranges around the projected total. The real cost will fall within the 80% interval about 80% of the time. |
229
+
230
+ ## Local API Server
231
+
232
+ `forecost serve` starts a local HTTP server (default port 8787) for programmatic access:
233
+
234
+ | Endpoint | Description |
235
+ |----------|-------------|
236
+ | `GET /api/health` | Health check. Returns `{"status": "ok"}`. |
237
+ | `GET /api/forecast` | Full forecast result (same as `forecost forecast --json`). |
238
+ | `GET /api/status` | Project status: active days, actual spend, baseline info. |
239
+ | `GET /api/costs` | Recent usage logs. |
240
+
241
+ Run from your project directory so forecost can find `.forecost.toml`.
242
+
243
+ ## Contributing
244
+
245
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
246
+
247
+ ## License
248
+
249
+ MIT