Skip to content

Commit ca9158e

Browse files
committed
docs: add VitePress site
1 parent 9a6b696 commit ca9158e

File tree

9 files changed

+1116
-0
lines changed

9 files changed

+1116
-0
lines changed

.github/workflows/deploy.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Deploy VitePress site to Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: read
9+
pages: write
10+
id-token: write
11+
12+
concurrency:
13+
group: pages
14+
cancel-in-progress: false
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Setup Bun
26+
uses: oven-sh/setup-bun@v2
27+
28+
- name: Setup Pages
29+
uses: actions/configure-pages@v4
30+
31+
- name: Install dependencies
32+
run: bun install
33+
working-directory: docs-site
34+
35+
- name: Build with VitePress
36+
run: bun run docs:build
37+
working-directory: docs-site
38+
39+
- name: Upload artifact
40+
uses: actions/upload-pages-artifact@v3
41+
with:
42+
path: docs-site/.vitepress/dist
43+
44+
deploy:
45+
environment:
46+
name: github-pages
47+
url: ${{ steps.deployment.outputs.page_url }}
48+
needs: build
49+
runs-on: ubuntu-latest
50+
name: Deploy
51+
steps:
52+
- name: Deploy to GitHub Pages
53+
id: deployment
54+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,8 @@ Thumbs.db
3636
*.so
3737
*.dylib
3838
dist/
39+
40+
# Docs site (VitePress)
41+
docs-site/node_modules/
42+
docs-site/.vitepress/dist/
43+
docs-site/.vitepress/cache/

docs-site/.vitepress/config.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { defineConfig } from 'vitepress'
2+
import llmstxt from 'vitepress-plugin-llms'
3+
4+
export default defineConfig({
5+
title: 'ptk — python-token-killer',
6+
description: 'Stop paying for nulls. Token compression for Python LLM workflows.',
7+
base: '/python-token-killer/',
8+
9+
vite: {
10+
plugins: [
11+
llmstxt({
12+
domain: 'https://amahi2001.github.io/python-token-killer/',
13+
generateLLMsFullTxt: true,
14+
}),
15+
],
16+
},
17+
18+
themeConfig: {
19+
nav: [
20+
{ text: 'Guide', link: '/guide/getting-started' },
21+
{ text: 'API Reference', link: '/api/reference' },
22+
{
23+
text: 'GitHub',
24+
link: 'https://github.com/amahi2001/python-token-killer',
25+
},
26+
{
27+
text: 'PyPI',
28+
link: 'https://pypi.org/project/python-token-killer/',
29+
},
30+
],
31+
32+
sidebar: [
33+
{
34+
text: 'Getting Started',
35+
items: [{ text: 'Installation & First Use', link: '/guide/getting-started' }],
36+
},
37+
{
38+
text: 'Core Functions',
39+
items: [
40+
{ text: 'ptk / minimize / stats / detect_type', link: '/api/reference' },
41+
],
42+
},
43+
{
44+
text: 'Use Cases',
45+
items: [{ text: 'RAG, LangChain/LangGraph, CI Logs, Diffs', link: '/guide/use-cases' }],
46+
},
47+
{
48+
text: 'Contributing',
49+
items: [
50+
{
51+
text: 'Contributing Guide',
52+
link: 'https://github.com/amahi2001/python-token-killer/blob/main/CONTRIBUTING.md',
53+
},
54+
],
55+
},
56+
],
57+
58+
socialLinks: [
59+
{ icon: 'github', link: 'https://github.com/amahi2001/python-token-killer' },
60+
],
61+
62+
footer: {
63+
message: 'Released under the MIT License.',
64+
copyright: 'Copyright © 2024 amahi2001',
65+
},
66+
},
67+
})

docs-site/api/reference.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# API Reference
2+
3+
## `ptk(obj)` — callable shorthand
4+
5+
The module itself is callable. `ptk(obj)` is identical to `ptk.minimize(obj)`.
6+
7+
```python
8+
import ptk
9+
10+
ptk({"user": {"id": 1, "name": "Alice", "bio": None}})
11+
# → '{"user":{"id":1,"name":"Alice"}}'
12+
```
13+
14+
---
15+
16+
## `ptk.minimize(obj, *, aggressive=False, content_type=None, **kw) → str`
17+
18+
Compresses `obj` and returns a string. Never raises on valid Python objects.
19+
20+
### Parameters
21+
22+
| Parameter | Type | Default | Description |
23+
| --- | --- | --- | --- |
24+
| `obj` | `Any` || Any Python object |
25+
| `aggressive` | `bool` | `False` | Maximum compression: strips timestamps, sigs-only for code, errors-only for logs |
26+
| `content_type` | `str \| None` | `None` | Override auto-detection: `"dict"`, `"list"`, `"code"`, `"log"`, `"diff"`, `"text"` |
27+
| `strip_nulls` | `bool` | `True` | For dicts/lists: strip `None`, `""`, `[]`, `{}` |
28+
| `format` | `str` | `"json"` | Dict output format: `"json"`, `"kv"`, `"tabular"` |
29+
| `mode` | `str` | `"clean"` | Code output mode: `"clean"` or `"signatures"` |
30+
| `errors_only` | `bool` | `False` | For logs: keep only errors and stack traces |
31+
32+
### Examples
33+
34+
```python
35+
import ptk
36+
37+
# ── dict/list ────────────────────────────────────────────────
38+
ptk.minimize(api_response)
39+
# Strips None, "", [], {} recursively. Returns compact JSON.
40+
41+
ptk.minimize(records, format="tabular")
42+
# Uniform list of dicts → TSV-style table. 60–70% savings.
43+
44+
ptk.minimize(response, strip_nulls=False)
45+
# Preserve nulls when they carry semantic meaning.
46+
47+
# ── code ─────────────────────────────────────────────────────
48+
ptk.minimize(source_code)
49+
# Strips comments (preserves # noqa, # type: ignore, TODO).
50+
# Collapses docstrings to one line.
51+
52+
ptk.minimize(source_code, mode="signatures")
53+
# Returns function/class signatures only. Up to 89% savings.
54+
55+
ptk.minimize(source_code, aggressive=True)
56+
# Combines signature extraction with maximum noise removal.
57+
58+
# ── logs ─────────────────────────────────────────────────────
59+
ptk.minimize(ci_log)
60+
# Collapses duplicate lines with counts. Preserves stack traces.
61+
62+
ptk.minimize(ci_log, errors_only=True)
63+
# Keeps only ERROR/CRITICAL lines and their stack traces.
64+
65+
ptk.minimize(ci_log, aggressive=True)
66+
# errors_only + timestamp stripping + line dedup.
67+
68+
# ── diffs ────────────────────────────────────────────────────
69+
ptk.minimize(git_diff)
70+
# Folds unchanged context (@@...@@ blocks). Strips git noise:
71+
# index lines, old/new mode, binary indicators.
72+
73+
# ── text ─────────────────────────────────────────────────────
74+
ptk.minimize(prose)
75+
# Abbreviates verbose words: implementation→impl, configuration→config.
76+
# Removes filler phrases and stopwords.
77+
78+
# ── force type ───────────────────────────────────────────────
79+
ptk.minimize(text, content_type="code")
80+
# Treats any string as code regardless of content.
81+
```
82+
83+
---
84+
85+
## `ptk.stats(obj, **kw) → dict`
86+
87+
Same interface as `minimize`. Returns a dict with the compressed output plus token counts.
88+
89+
### Return value
90+
91+
```python
92+
{
93+
"output": str, # the compressed string
94+
"original_tokens": int, # token count before compression
95+
"minimized_tokens": int, # token count after compression
96+
"savings_pct": float, # percentage saved, e.g. 45.4
97+
"content_type": str, # detected or forced type
98+
}
99+
```
100+
101+
`original_tokens` and `minimized_tokens` use `tiktoken` (`cl100k_base`) when installed. Without it, they fall back to `len(text) // 4`.
102+
103+
### Example
104+
105+
```python
106+
import ptk
107+
108+
result = ptk.stats(api_response)
109+
print(f"Saved {result['savings_pct']:.1f}% ({result['original_tokens']}{result['minimized_tokens']} tokens)")
110+
# → Saved 45.4% (1450 → 792 tokens)
111+
```
112+
113+
---
114+
115+
## `ptk.detect_type(obj) → str`
116+
117+
Returns the detected content type without compressing.
118+
119+
```python
120+
ptk.detect_type({"key": "value"}) # → "dict"
121+
ptk.detect_type([1, 2, 3]) # → "list"
122+
ptk.detect_type("def foo():\n pass") # → "code"
123+
ptk.detect_type("ERROR: connection refused\nTraceback...") # → "log"
124+
ptk.detect_type("@@ -1,3 +1,4 @@\n+new line") # → "diff"
125+
ptk.detect_type("Some prose text.") # → "text"
126+
```
127+
128+
Detection is fast: O(1) for non-strings (checks Python type), 2KB scan for strings.
129+
130+
---
131+
132+
## Content type strategies
133+
134+
| Type | Trigger | Key savings |
135+
| --- | --- | --- |
136+
| `dict` | `isinstance(obj, dict)` | Null stripping, key shortening, tabular encoding |
137+
| `list` | `isinstance(obj, list)` | Schema-once tabular, dedup with counts, sampling |
138+
| `code` | `def `, `class `, `import ` in first 2KB | Comment strip (pragma-safe), docstring collapse, sig extraction |
139+
| `log` | `ERROR`, `WARNING`, `Traceback` in first 2KB | Line dedup with counts, error filter, stack trace preservation |
140+
| `diff` | `@@` or `+++ ` / `--- ` in first 2KB | Context folding, git noise strip |
141+
| `text` | fallback for all strings | Word abbreviation, filler removal, stopword removal |
142+
143+
---
144+
145+
## Error handling guarantees
146+
147+
- `minimize()` **never raises** on valid Python objects. `RecursionError`, `ValueError`, `TypeError`, `OverflowError` inside a minimizer all fall back to `str(obj)`.
148+
- `minimize()` **never mutates** the input. Verified by deepcopy comparison in the test suite.
149+
- The module is **thread-safe**. Minimizers are stateless singletons.

0 commit comments

Comments
 (0)