peekai 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.
- peekai-0.1.0/.env.example +14 -0
- peekai-0.1.0/.github/workflows/ci.yml +41 -0
- peekai-0.1.0/.github/workflows/publish.yml +41 -0
- peekai-0.1.0/.gitignore +211 -0
- peekai-0.1.0/.streamlit/config.toml +15 -0
- peekai-0.1.0/BACKLOG.md +155 -0
- peekai-0.1.0/CHANGELOG.md +54 -0
- peekai-0.1.0/CONTRIBUTING.md +109 -0
- peekai-0.1.0/LICENSE +21 -0
- peekai-0.1.0/PKG-INFO +344 -0
- peekai-0.1.0/README.md +295 -0
- peekai-0.1.0/examples/demo_agent.py +112 -0
- peekai-0.1.0/examples/demo_multi_agent.py +100 -0
- peekai-0.1.0/pyproject.toml +105 -0
- peekai-0.1.0/src/peekai/__init__.py +152 -0
- peekai-0.1.0/src/peekai/cli/__init__.py +1 -0
- peekai-0.1.0/src/peekai/cli/banner.py +130 -0
- peekai-0.1.0/src/peekai/cli/commands/__init__.py +1 -0
- peekai-0.1.0/src/peekai/cli/commands/clear.py +26 -0
- peekai-0.1.0/src/peekai/cli/commands/list_traces.py +68 -0
- peekai-0.1.0/src/peekai/cli/commands/map_trace.py +122 -0
- peekai-0.1.0/src/peekai/cli/commands/replay.py +178 -0
- peekai-0.1.0/src/peekai/cli/commands/stats.py +67 -0
- peekai-0.1.0/src/peekai/cli/commands/ui.py +36 -0
- peekai-0.1.0/src/peekai/cli/commands/view.py +136 -0
- peekai-0.1.0/src/peekai/cli/console.py +35 -0
- peekai-0.1.0/src/peekai/cli/main.py +73 -0
- peekai-0.1.0/src/peekai/core/__init__.py +1 -0
- peekai-0.1.0/src/peekai/core/costs.py +103 -0
- peekai-0.1.0/src/peekai/core/models.py +155 -0
- peekai-0.1.0/src/peekai/core/storage.py +348 -0
- peekai-0.1.0/src/peekai/core/tracer.py +308 -0
- peekai-0.1.0/src/peekai/patches/__init__.py +1 -0
- peekai-0.1.0/src/peekai/patches/_stream.py +254 -0
- peekai-0.1.0/src/peekai/patches/anthropic_patch.py +191 -0
- peekai-0.1.0/src/peekai/patches/litellm_patch.py +150 -0
- peekai-0.1.0/src/peekai/patches/openai_patch.py +180 -0
- peekai-0.1.0/src/peekai/patches/registry.py +31 -0
- peekai-0.1.0/src/peekai/py.typed +0 -0
- peekai-0.1.0/src/peekai/replay/__init__.py +1 -0
- peekai-0.1.0/src/peekai/replay/engine.py +259 -0
- peekai-0.1.0/src/peekai/ui/__init__.py +1 -0
- peekai-0.1.0/src/peekai/ui/app.py +877 -0
- peekai-0.1.0/src/peekai/ui/favicon.svg +4 -0
- peekai-0.1.0/src/peekai/ui/peekai-logo.png +0 -0
- peekai-0.1.0/src/peekai/ui/peekai-name-logo.png +0 -0
- peekai-0.1.0/src/peekai/ui/styles.py +290 -0
- peekai-0.1.0/tests/__init__.py +1 -0
- peekai-0.1.0/tests/test_costs.py +52 -0
- peekai-0.1.0/tests/test_init.py +21 -0
- peekai-0.1.0/tests/test_replay.py +42 -0
- peekai-0.1.0/tests/test_storage.py +178 -0
- peekai-0.1.0/tests/test_streaming.py +131 -0
- peekai-0.1.0/tests/test_tracer.py +313 -0
- peekai-0.1.0/uv.lock +3106 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# PeekAI Demo Environment Variables
|
|
2
|
+
#
|
|
3
|
+
# Copy this file to .env and fill in your credentials:
|
|
4
|
+
# cp .env.example .env
|
|
5
|
+
#
|
|
6
|
+
# ⚠️ Never commit .env to version control!
|
|
7
|
+
# It's already in .gitignore
|
|
8
|
+
|
|
9
|
+
# Your OpenAI API key (required for demos)
|
|
10
|
+
OPENAI_API_KEY=sk-your-api-key-here
|
|
11
|
+
|
|
12
|
+
# Optional: Custom base URL for OpenAI-compatible endpoints
|
|
13
|
+
# Default: https://api.openai.com/v1
|
|
14
|
+
OPENAI_BASE_URL=https://api.openai.com/v1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main"]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@v5
|
|
25
|
+
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv sync --extra dev
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: uv run ruff check src/
|
|
36
|
+
|
|
37
|
+
- name: Type check
|
|
38
|
+
run: uv run mypy src/peekai/
|
|
39
|
+
|
|
40
|
+
- name: Test
|
|
41
|
+
run: uv run pytest tests/ -v
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*" # triggers on v0.1.0, v1.2.3, etc.
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-and-publish:
|
|
10
|
+
name: Build and publish
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
environment: pypi # matches the trusted publisher environment on PyPI
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
id-token: write # required for OIDC trusted publishing (no API key needed)
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
- name: Build distributions
|
|
30
|
+
run: uv build
|
|
31
|
+
|
|
32
|
+
- name: Publish to PyPI
|
|
33
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
34
|
+
# Uses OIDC trusted publishing — no PYPI_API_TOKEN secret needed.
|
|
35
|
+
# Configure the trusted publisher on PyPI:
|
|
36
|
+
# https://pypi.org/manage/account/publishing/
|
|
37
|
+
# Publisher: GitHub Actions
|
|
38
|
+
# Owner: peekai
|
|
39
|
+
# Repo: peekai
|
|
40
|
+
# Workflow: publish.yml
|
|
41
|
+
# Env: pypi
|
peekai-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# uv.lock is committed for applications, ignored for libraries.
|
|
99
|
+
# PeekAI is a library/tool — keeping lock out of VCS until v0.1 ships.
|
|
100
|
+
#uv.lock
|
|
101
|
+
|
|
102
|
+
# poetry
|
|
103
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
104
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
105
|
+
# commonly ignored for libraries.
|
|
106
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
107
|
+
#poetry.lock
|
|
108
|
+
#poetry.toml
|
|
109
|
+
|
|
110
|
+
# pdm
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
112
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
113
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
114
|
+
#pdm.lock
|
|
115
|
+
#pdm.toml
|
|
116
|
+
.pdm-python
|
|
117
|
+
.pdm-build/
|
|
118
|
+
|
|
119
|
+
# pixi
|
|
120
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
121
|
+
#pixi.lock
|
|
122
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
123
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
124
|
+
.pixi
|
|
125
|
+
|
|
126
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
127
|
+
__pypackages__/
|
|
128
|
+
|
|
129
|
+
# Celery stuff
|
|
130
|
+
celerybeat-schedule
|
|
131
|
+
celerybeat.pid
|
|
132
|
+
|
|
133
|
+
# SageMath parsed files
|
|
134
|
+
*.sage.py
|
|
135
|
+
|
|
136
|
+
# Environments
|
|
137
|
+
.env
|
|
138
|
+
.envrc
|
|
139
|
+
.venv
|
|
140
|
+
env/
|
|
141
|
+
venv/
|
|
142
|
+
ENV/
|
|
143
|
+
env.bak/
|
|
144
|
+
venv.bak/
|
|
145
|
+
|
|
146
|
+
# Spyder project settings
|
|
147
|
+
.spyderproject
|
|
148
|
+
.spyproject
|
|
149
|
+
|
|
150
|
+
# Rope project settings
|
|
151
|
+
.ropeproject
|
|
152
|
+
|
|
153
|
+
# mkdocs documentation
|
|
154
|
+
/site
|
|
155
|
+
|
|
156
|
+
# mypy
|
|
157
|
+
.mypy_cache/
|
|
158
|
+
.dmypy.json
|
|
159
|
+
dmypy.json
|
|
160
|
+
|
|
161
|
+
# Pyre type checker
|
|
162
|
+
.pyre/
|
|
163
|
+
|
|
164
|
+
# pytype static type analyzer
|
|
165
|
+
.pytype/
|
|
166
|
+
|
|
167
|
+
# Cython debug symbols
|
|
168
|
+
cython_debug/
|
|
169
|
+
|
|
170
|
+
# PyCharm
|
|
171
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
172
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
173
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
174
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
175
|
+
.idea/
|
|
176
|
+
|
|
177
|
+
# Abstra
|
|
178
|
+
# Abstra is an AI-powered process automation framework.
|
|
179
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
180
|
+
# Learn more at https://abstra.io/docs
|
|
181
|
+
.abstra/
|
|
182
|
+
|
|
183
|
+
# Visual Studio Code
|
|
184
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
185
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
186
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
187
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
188
|
+
# .vscode/
|
|
189
|
+
|
|
190
|
+
# Ruff stuff:
|
|
191
|
+
.ruff_cache/
|
|
192
|
+
|
|
193
|
+
# PyPI configuration file
|
|
194
|
+
.pypirc
|
|
195
|
+
|
|
196
|
+
# Cursor
|
|
197
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
198
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
199
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
200
|
+
.cursorignore
|
|
201
|
+
.cursorindexingignore
|
|
202
|
+
|
|
203
|
+
# Marimo
|
|
204
|
+
marimo/_static/
|
|
205
|
+
marimo/_lsp/
|
|
206
|
+
__marimo__/
|
|
207
|
+
|
|
208
|
+
# PeekAI
|
|
209
|
+
*.peekai.db
|
|
210
|
+
peekai.db
|
|
211
|
+
.peekai/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[theme]
|
|
2
|
+
base = "light"
|
|
3
|
+
primaryColor = "#ff6600"
|
|
4
|
+
backgroundColor = "#f8fafc"
|
|
5
|
+
secondaryBackgroundColor = "#ffffff"
|
|
6
|
+
textColor = "#0f172a"
|
|
7
|
+
|
|
8
|
+
[server]
|
|
9
|
+
headless = true
|
|
10
|
+
|
|
11
|
+
[browser]
|
|
12
|
+
gatherUsageStats = false
|
|
13
|
+
|
|
14
|
+
[logger]
|
|
15
|
+
level = "error"
|
peekai-0.1.0/BACKLOG.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# PeekAI — Product Backlog
|
|
2
|
+
|
|
3
|
+
> 👀 Lightweight, local-first observability and debugging for Python AI agents.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## How to use this backlog
|
|
8
|
+
|
|
9
|
+
- Keep this file in `docs/BACKLOG.md` inside your repo
|
|
10
|
+
- Use GitHub Projects as your weekly kanban board
|
|
11
|
+
- Every Sunday: pick tasks for the week and move them to "This Week"
|
|
12
|
+
- Update status here monthly as phases complete
|
|
13
|
+
|
|
14
|
+
**Status legend:** `⬜ Todo` `🔵 In Progress` `✅ Done`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Phase 0 — Project Setup
|
|
19
|
+
> Goal: clean foundation before any real code
|
|
20
|
+
|
|
21
|
+
| Status | Task | Priority | Effort |
|
|
22
|
+
|--------|------|----------|--------|
|
|
23
|
+
| ✅ | Set up project structure and folders | High | 30 min |
|
|
24
|
+
| ⬜ | Set up virtual environment | High | 15 min |
|
|
25
|
+
| ✅ | Create `pyproject.toml` with project metadata | High | 30 min |
|
|
26
|
+
| ✅ | Add `.gitignore` for Python + SQLite | High | 10 min |
|
|
27
|
+
| ✅ | Write initial README with vision + install preview | High | 45 min |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Phase 1 — Core SDK (Instrumentation Layer)
|
|
32
|
+
> Goal: capture a real trace from a real OpenAI call
|
|
33
|
+
|
|
34
|
+
| Status | Task | Priority | Effort |
|
|
35
|
+
|--------|------|----------|--------|
|
|
36
|
+
| ✅ | Create `Span` and `Trace` dataclasses | High | 1 hr |
|
|
37
|
+
| ✅ | Build `Tracer` class with `ContextVar` for async safety | High | 2 hrs |
|
|
38
|
+
| ✅ | Build `Storage` class with SQLite via `sqlite3` | High | 2 hrs |
|
|
39
|
+
| ✅ | Implement OpenAI SDK monkey-patch | High | 3 hrs |
|
|
40
|
+
| ✅ | Implement Anthropic SDK monkey-patch | High | 2 hrs |
|
|
41
|
+
| ✅ | Implement LiteLLM monkey-patch | Medium | 2 hrs |
|
|
42
|
+
| ✅ | Token tracking per span | High | 1 hr |
|
|
43
|
+
| ✅ | Cost calculation per span per model | High | 1 hr |
|
|
44
|
+
| ✅ | Error capture with full context | High | 1 hr |
|
|
45
|
+
| ✅ | `peekai.init()` auto-patches all installed SDKs | High | 1 hr |
|
|
46
|
+
| ✅ | `@peekai.trace()` decorator for agent runs | High | 1 hr |
|
|
47
|
+
| ✅ | Tool call tracking via decorator | Medium | 2 hrs |
|
|
48
|
+
| ✅ | Write unit tests for tracer and storage | Medium | 2 hrs |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Phase 2 — CLI
|
|
53
|
+
> Goal: fully usable without any UI at all
|
|
54
|
+
|
|
55
|
+
| Status | Task | Priority | Effort |
|
|
56
|
+
|--------|------|----------|--------|
|
|
57
|
+
| ✅ | Set up Typer CLI skeleton | High | 30 min |
|
|
58
|
+
| ✅ | `peekai list` — show last 10 traces | High | 1 hr |
|
|
59
|
+
| ✅ | `peekai view <trace-id>` — pretty print trace | High | 2 hrs |
|
|
60
|
+
| ✅ | `peekai stats` — total cost, tokens, runs | Medium | 1 hr |
|
|
61
|
+
| ✅ | `peekai clear` — wipe local storage | Medium | 30 min |
|
|
62
|
+
| ✅ | `peekai ui` — launch Streamlit UI | High | 30 min |
|
|
63
|
+
| ✅ | Colorized terminal output with `rich` | Medium | 1 hr |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 3 — Streamlit Web UI
|
|
68
|
+
> Goal: something you'd screenshot and post on Twitter
|
|
69
|
+
|
|
70
|
+
| Status | Task | Priority | Effort |
|
|
71
|
+
|--------|------|----------|--------|
|
|
72
|
+
| ✅ | Trace list view with status, cost, duration | High | 2 hrs |
|
|
73
|
+
| ✅ | Trace detail waterfall view (span by span) | High | 3 hrs |
|
|
74
|
+
| ✅ | Token + cost breakdown per span | High | 1 hr |
|
|
75
|
+
| ✅ | Error highlighting in trace view | High | 1 hr |
|
|
76
|
+
| ✅ | Filter traces by status, model, date | Medium | 2 hrs |
|
|
77
|
+
| ✅ | JSON input/output viewer per span | Medium | 1 hr |
|
|
78
|
+
| ✅ | Total dashboard — runs, cost, tokens over time | Medium | 2 hrs |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Phase 4 — Trace Replay (Differentiator)
|
|
83
|
+
> Goal: re-run any past trace — the killer feature
|
|
84
|
+
|
|
85
|
+
| Status | Task | Priority | Effort |
|
|
86
|
+
|--------|------|----------|--------|
|
|
87
|
+
| ✅ | Store full prompt + response per span in SQLite | High | 1 hr |
|
|
88
|
+
| ✅ | `peekai replay <trace-id>` CLI command | High | 3 hrs |
|
|
89
|
+
| ✅ | Replay with model swap (GPT-4o vs Claude) | High | 3 hrs |
|
|
90
|
+
| ✅ | Replay with modified tool response | Medium | 4 hrs |
|
|
91
|
+
| ✅ | Side by side original vs replayed trace in UI | Medium | 3 hrs |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Phase 5 — Multi-Agent Support
|
|
96
|
+
> Goal: visualize agent-to-agent calls
|
|
97
|
+
|
|
98
|
+
| Status | Task | Priority | Effort |
|
|
99
|
+
|--------|------|----------|--------|
|
|
100
|
+
| ✅ | Parent/child span relationship in data model | High | 2 hrs |
|
|
101
|
+
| ✅ | Agent handoff tracking via context propagation | High | 3 hrs |
|
|
102
|
+
| ✅ | Multi-agent waterfall tree view in UI | High | 4 hrs |
|
|
103
|
+
| ✅ | `peekai map <trace-id>` — ASCII agent flow in CLI | Medium | 2 hrs |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Phase 6 — Polish + Ship v0.1
|
|
108
|
+
> Goal: public release, real people using it
|
|
109
|
+
|
|
110
|
+
| Status | Task | Priority | Effort |
|
|
111
|
+
|--------|------|----------|--------|
|
|
112
|
+
| ✅ | Write proper README with badges + demo gif | High | 2 hrs |
|
|
113
|
+
| ⬜ | Record demo gif with a real agent example | High | 1 hr |
|
|
114
|
+
| ✅ | Write `CONTRIBUTING.md` | Medium | 1 hr |
|
|
115
|
+
| 🔵 | Publish to PyPI | High | 1 hr |
|
|
116
|
+
| ⬜ | Post on HackerNews — Show HN | High | 30 min |
|
|
117
|
+
| ⬜ | Post on Reddit r/LocalLLaMA + r/Python | High | 30 min |
|
|
118
|
+
| ⬜ | Post demo gif on X/Twitter | High | 15 min |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## V2 Backlog — Do not touch until real users ask
|
|
123
|
+
> Ideas for after v0.1 is live and people are using it
|
|
124
|
+
|
|
125
|
+
- [ ] Eval hooks — attach pass/fail criteria to a trace
|
|
126
|
+
- [ ] Failure clustering — group similar errors across runs automatically
|
|
127
|
+
- [ ] Agent diff — compare two runs side by side
|
|
128
|
+
- [ ] Export to Langfuse / OpenTelemetry format
|
|
129
|
+
- [ ] VS Code extension
|
|
130
|
+
- [ ] GitHub Action for CI agent testing
|
|
131
|
+
- [ ] Async agent support improvements
|
|
132
|
+
- [ ] Custom span types for domain-specific agents
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Weekly Routine
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Sunday evening (15 min):
|
|
140
|
+
→ Review Done column
|
|
141
|
+
→ Pick next week tasks from Backlog
|
|
142
|
+
→ Move to "This Week" on GitHub Projects
|
|
143
|
+
|
|
144
|
+
Weekday evenings (1.5 hrs):
|
|
145
|
+
→ 15 min: review board, pick one task
|
|
146
|
+
→ 60 min: build only
|
|
147
|
+
→ 15 min: commit, update board, note where you stopped
|
|
148
|
+
|
|
149
|
+
Weekend (4-5 hrs/day):
|
|
150
|
+
→ Bigger tasks, integrations, UI work
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
*Last updated: April 2026*
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to PeekAI will be documented here.
|
|
4
|
+
|
|
5
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
+
Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [0.1.0] — Unreleased
|
|
11
|
+
|
|
12
|
+
First public release.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
**Core**
|
|
17
|
+
- `Trace` and `Span` dataclasses with full token, cost, and timing tracking
|
|
18
|
+
- `Tracer` with `ContextVar`-based async/thread safety for nested span trees
|
|
19
|
+
- SQLite storage at `~/.peekai/peekai.db` with WAL mode and indexed queries
|
|
20
|
+
- Token cost table for OpenAI and Anthropic models with LiteLLM fallback
|
|
21
|
+
|
|
22
|
+
**SDK patches** (auto-applied at `peekai.init()`)
|
|
23
|
+
- OpenAI — sync + async `chat.completions.create`, including `stream=True`
|
|
24
|
+
- Anthropic — sync + async `messages.create`, including `stream=True`
|
|
25
|
+
- LiteLLM — sync + async `completion`
|
|
26
|
+
|
|
27
|
+
**Decorators**
|
|
28
|
+
- `@peekai.trace("name")` — wraps a function as a top-level trace
|
|
29
|
+
- `@peekai.agent("name")` — wraps a sub-agent, LLM calls become children in the tree
|
|
30
|
+
- `@peekai.tool("name")` — wraps a tool call as a TOOL span
|
|
31
|
+
|
|
32
|
+
**CLI** (`peekai <command>`)
|
|
33
|
+
- `list` — show recent traces with status, tokens, cost, duration
|
|
34
|
+
- `view <id>` — full span waterfall with input/output/tool call detail
|
|
35
|
+
- `map <id>` — ASCII agent flow tree with nested parent/child spans
|
|
36
|
+
- `stats` — aggregate token + cost totals grouped by model
|
|
37
|
+
- `replay <id>` — re-run a trace with optional `--model` and `--tool` overrides
|
|
38
|
+
- `ui` — launch the Streamlit dashboard
|
|
39
|
+
- `clear` — wipe all local storage
|
|
40
|
+
|
|
41
|
+
**Web dashboard** (`peekai ui`)
|
|
42
|
+
- Dashboard page — KPIs, cost over time, per-model breakdown
|
|
43
|
+
- Traces page — filterable list with status, tokens, cost
|
|
44
|
+
- Trace view — span waterfall with duration bars, I/O tabs, error highlighting
|
|
45
|
+
- Replay page — side-by-side comparison with token/cost deltas
|
|
46
|
+
|
|
47
|
+
**Trace replay**
|
|
48
|
+
- Re-send stored prompts to any OpenAI-compatible or Anthropic model
|
|
49
|
+
- Inject modified tool responses via `--tool name=value`
|
|
50
|
+
- Replay saved as a new linked trace
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
[0.1.0]: https://github.com/peekai/peekai/releases/tag/v0.1.0
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Contributing to PeekAI
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing. PeekAI is a small, focused tool — contributions that keep it simple and local-first are most welcome.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Getting started
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/peekai/peekai
|
|
11
|
+
cd peekai
|
|
12
|
+
uv sync --extra all
|
|
13
|
+
uv run pytest tests/ -v
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
That's it. No Docker, no external services, no environment variables needed to run the tests.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Project structure
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
src/peekai/
|
|
24
|
+
├── __init__.py # public API: init(), trace(), agent(), tool()
|
|
25
|
+
├── core/
|
|
26
|
+
│ ├── models.py # Span, Trace dataclasses
|
|
27
|
+
│ ├── tracer.py # Tracer with ContextVar async safety
|
|
28
|
+
│ ├── storage.py # SQLite storage layer
|
|
29
|
+
│ └── costs.py # Token cost table per model
|
|
30
|
+
├── patches/
|
|
31
|
+
│ ├── openai_patch.py # OpenAI SDK monkey-patch
|
|
32
|
+
│ ├── anthropic_patch.py
|
|
33
|
+
│ └── litellm_patch.py
|
|
34
|
+
├── cli/
|
|
35
|
+
│ ├── main.py # Typer app + command registration
|
|
36
|
+
│ ├── console.py # Shared Rich console
|
|
37
|
+
│ └── commands/ # One file per CLI command
|
|
38
|
+
├── ui/
|
|
39
|
+
│ ├── app.py # Streamlit dashboard
|
|
40
|
+
│ └── styles.py # Inline HTML/CSS helpers
|
|
41
|
+
└── replay/
|
|
42
|
+
└── engine.py # Trace replay engine
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## How to contribute
|
|
48
|
+
|
|
49
|
+
### Bug fixes
|
|
50
|
+
Open an issue first if it's non-trivial. For small fixes, a PR is fine directly.
|
|
51
|
+
|
|
52
|
+
### New features
|
|
53
|
+
Open an issue to discuss before building. PeekAI is intentionally minimal — features that add cloud dependencies, require external services, or significantly increase complexity are unlikely to be merged into v0.x.
|
|
54
|
+
|
|
55
|
+
### Adding a new SDK patch
|
|
56
|
+
1. Create `src/peekai/patches/<sdk>_patch.py`
|
|
57
|
+
2. Implement `patch(tracer)` and `unpatch()` following the existing pattern
|
|
58
|
+
3. Register it in `src/peekai/__init__.py` inside `init()`
|
|
59
|
+
4. Add a test in `tests/`
|
|
60
|
+
|
|
61
|
+
### Adding a model to the cost table
|
|
62
|
+
Edit `src/peekai/core/costs.py` — add the model name and `(input_per_1k, output_per_1k)` tuple. Include a source link in the PR description.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Code style
|
|
67
|
+
|
|
68
|
+
- **Formatter**: `ruff format` (line length 88)
|
|
69
|
+
- **Linter**: `ruff check`
|
|
70
|
+
- **Types**: mypy strict — all public functions need type annotations
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv run ruff check src/
|
|
74
|
+
uv run ruff format src/
|
|
75
|
+
uv run mypy src/peekai/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Tests
|
|
81
|
+
|
|
82
|
+
All tests live in `tests/`. Run them with:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv run pytest tests/ -v
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- Tests use `tmp_path` fixtures for SQLite — no shared state between tests
|
|
89
|
+
- No mocking of the OpenAI/Anthropic clients in unit tests — patches are tested via the tracer directly
|
|
90
|
+
- New features should include at least one test
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Pull request checklist
|
|
95
|
+
|
|
96
|
+
- [ ] Tests pass (`uv run pytest tests/ -v`)
|
|
97
|
+
- [ ] No new ruff errors (`uv run ruff check src/`)
|
|
98
|
+
- [ ] Type annotations on new public functions
|
|
99
|
+
- [ ] BACKLOG.md updated if a tracked task is completed
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Reporting issues
|
|
104
|
+
|
|
105
|
+
Include:
|
|
106
|
+
- Python version (`python --version`)
|
|
107
|
+
- PeekAI version (`peekai --version` or check `pyproject.toml`)
|
|
108
|
+
- Minimal reproduction script
|
|
109
|
+
- Full error traceback
|
peekai-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OussamaKH
|
|
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.
|