|
| 1 | +# AGON Playground Implementation Plan |
| 2 | + |
| 3 | +## Overview |
| 4 | +Add an interactive playground to the MkDocs documentation where users can: |
| 5 | +1. Input JSON data and see real-time encoding in all 4 AGON formats |
| 6 | +2. Compare token counts and savings across formats |
| 7 | +3. See which format would be auto-selected |
| 8 | +4. Edit and experiment with different data shapes |
| 9 | + |
| 10 | +## Technical Approach |
| 11 | + |
| 12 | +### Challenge |
| 13 | +AGON is implemented in Rust with Python bindings - cannot run directly in the browser. |
| 14 | + |
| 15 | +### Solution: Pure JavaScript Implementation |
| 16 | +Implement lightweight JavaScript versions of the encoders for the playground. This provides: |
| 17 | +- Zero latency (no server round-trips) |
| 18 | +- Works offline |
| 19 | +- Self-contained in docs |
| 20 | +- No backend infrastructure needed |
| 21 | + |
| 22 | +The encoding formats are simple string transformations that can be ported accurately to JavaScript. |
| 23 | + |
| 24 | +## Implementation Plan |
| 25 | + |
| 26 | +### 1. Create Playground Page |
| 27 | +**File:** `docs/playground.md` |
| 28 | + |
| 29 | +- New documentation page with embedded playground |
| 30 | +- JSON editor input area |
| 31 | +- Output panels for each format (JSON, Rows, Columns, Struct) |
| 32 | +- Token count comparison chart |
| 33 | +- Auto-format recommendation indicator |
| 34 | + |
| 35 | +### 2. Create JavaScript Encoder Module |
| 36 | +**File:** `docs/javascripts/agon-playground.js` |
| 37 | + |
| 38 | +Implement: |
| 39 | +- `encodeRows(data)` - AGONRows format encoder |
| 40 | +- `encodeColumns(data)` - AGONColumns format encoder |
| 41 | +- `encodeStruct(data)` - AGONStruct format encoder |
| 42 | +- `estimateTokens(text)` - Simple token estimation (chars/4 or GPT tokenizer) |
| 43 | +- `autoSelect(data)` - Format selection logic with min_savings threshold |
| 44 | + |
| 45 | +### 3. Create Playground UI Component |
| 46 | +**File:** `docs/javascripts/playground-ui.js` |
| 47 | + |
| 48 | +Features: |
| 49 | +- **Monaco Editor** for JSON input (VS Code editor with full syntax highlighting, auto-completion, JSON validation) |
| 50 | +- Live encoding preview (debounced for performance) |
| 51 | +- Tab panels for each encoding output |
| 52 | +- Token savings visualization (reuse Chart.js from benchmarks) |
| 53 | +- Copy-to-clipboard buttons |
| 54 | +- Example data dropdown (pre-loaded examples from benchmarks) |
| 55 | +- Error handling for invalid JSON |
| 56 | + |
| 57 | +**Monaco Setup:** |
| 58 | +- Load from CDN: `monaco-editor` via `@monaco-editor/loader` |
| 59 | +- Configure for JSON language with schema validation |
| 60 | +- Theme sync with MkDocs light/dark mode |
| 61 | + |
| 62 | +### 4. Add Styling |
| 63 | +**File:** `docs/stylesheets/playground.css` |
| 64 | + |
| 65 | +- Responsive two-column layout (input | output) |
| 66 | +- Dark/light mode support (matches Material theme) |
| 67 | +- Syntax highlighting for output formats |
| 68 | +- Mobile-friendly collapsible panels |
| 69 | + |
| 70 | +### 5. Update MkDocs Configuration |
| 71 | +**File:** `mkdocs.yml` |
| 72 | + |
| 73 | +- Add playground to navigation |
| 74 | +- Include new JavaScript/CSS files |
| 75 | +- Add extra_css entry |
| 76 | + |
| 77 | +## Files to Create/Modify |
| 78 | + |
| 79 | +| File | Action | Description | |
| 80 | +|------|--------|-------------| |
| 81 | +| `docs/playground.md` | Create | Playground page with HTML structure | |
| 82 | +| `docs/javascripts/agon-playground.js` | Create | Core encoding logic in JS | |
| 83 | +| `docs/javascripts/playground-ui.js` | Create | UI interactions and rendering | |
| 84 | +| `docs/stylesheets/playground.css` | Create | Playground styling | |
| 85 | +| `mkdocs.yml` | Modify | Add nav entry and extra files | |
| 86 | + |
| 87 | +## External Dependencies (CDN) |
| 88 | + |
| 89 | +| Library | Purpose | Size | CDN | |
| 90 | +|---------|---------|------|-----| |
| 91 | +| Monaco Editor | JSON input editor | ~2MB | jsdelivr | |
| 92 | +| js-tiktoken | Accurate token counting | ~300KB | jsdelivr | |
| 93 | +| Chart.js | Already included | - | Already in mkdocs.yml | |
| 94 | + |
| 95 | +## Encoding Implementation Details |
| 96 | + |
| 97 | +### AGONRows Encoder (JS) |
| 98 | +```javascript |
| 99 | +// Input: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}] |
| 100 | +// Output: [2]{id name} |
| 101 | +// 1 Alice |
| 102 | +// 2 Bob |
| 103 | +``` |
| 104 | + |
| 105 | +Key logic: |
| 106 | +1. Detect if data is uniform array of objects |
| 107 | +2. Extract field names from first object |
| 108 | +3. Generate header `[count]{field1 field2 ...}` |
| 109 | +4. Render each row with tab-delimited values |
| 110 | +5. Handle nested objects with indentation |
| 111 | + |
| 112 | +### AGONColumns Encoder (JS) |
| 113 | +```javascript |
| 114 | +// Input: [{id: 1, name: "Alice"}, {id: 2, name: "Bob"}] |
| 115 | +// Output: [2] |
| 116 | +// ├ id: 1 2 |
| 117 | +// └ name: Alice Bob |
| 118 | +``` |
| 119 | + |
| 120 | +Key logic: |
| 121 | +1. Transpose data (group by field instead of row) |
| 122 | +2. Generate `[count]` header |
| 123 | +3. Render each field with tree chars (├ / └) |
| 124 | +4. Tab-delimit values within each field line |
| 125 | + |
| 126 | +### AGONStruct Encoder (JS) |
| 127 | +```javascript |
| 128 | +// Input: {price: {fmt: "$100", raw: 100}, change: {fmt: "+5", raw: 5}} |
| 129 | +// Output: @FR: fmt, raw |
| 130 | +// |
| 131 | +// price: FR($100, 100) |
| 132 | +// change: FR(+5, 5) |
| 133 | +``` |
| 134 | + |
| 135 | +Key logic: |
| 136 | +1. Detect repeated object patterns (same field structure) |
| 137 | +2. Generate template definition if ≥3 occurrences |
| 138 | +3. Replace instances with template calls |
| 139 | + |
| 140 | +### Token Counting (Accurate) |
| 141 | +Use **js-tiktoken** for GPT-accurate token counts: |
| 142 | +- Load `tiktoken` from npm CDN (jsdelivr/unpkg) |
| 143 | +- Use `o200k_base` encoding (GPT-4o default, matches AGON's default) |
| 144 | +- Lazy-load tokenizer on first use to avoid blocking page load |
| 145 | +- Cache tokenizer instance for subsequent calculations |
| 146 | + |
| 147 | +## UI Layout |
| 148 | + |
| 149 | +``` |
| 150 | +┌─────────────────────────────────────────────────────────────┐ |
| 151 | +│ AGON Playground [Load Example ▼] │ |
| 152 | +├───────────────────────────┬─────────────────────────────────┤ |
| 153 | +│ JSON Input │ Encoded Output │ |
| 154 | +│ ┌─────────────────────┐ │ ┌───────────────────────────┐ │ |
| 155 | +│ │ { │ │ │ [JSON] [Rows] [Cols] [St] │ │ |
| 156 | +│ │ "users": [ │ │ ├───────────────────────────┤ │ |
| 157 | +│ │ {"id": 1, ... │ │ │ [2]{id name} │ │ |
| 158 | +│ │ ] │ │ │ 1 Alice │ │ |
| 159 | +│ │ } │ │ │ 2 Bob │ │ |
| 160 | +│ └─────────────────────┘ │ └───────────────────────────┘ │ |
| 161 | +│ │ │ |
| 162 | +│ ┌─────────────────────────────────────────────────────────┐│ |
| 163 | +│ │ Token Comparison Chart ││ |
| 164 | +│ │ [====== JSON 45 ======] ││ |
| 165 | +│ │ [=== Rows 26 ===] ✓ Best (-42%) ││ |
| 166 | +│ │ [==== Cols 30 ====] ││ |
| 167 | +│ │ [===== Struct 35 =====] ││ |
| 168 | +│ └─────────────────────────────────────────────────────────┘│ |
| 169 | +└─────────────────────────────────────────────────────────────┘ |
| 170 | +``` |
| 171 | + |
| 172 | +## Example Data Options |
| 173 | + |
| 174 | +Pre-loaded examples from benchmark data: |
| 175 | +1. User list (simple - Rows wins) |
| 176 | +2. Employee records (wide - Columns wins) |
| 177 | +3. Market data (nested patterns - Struct wins) |
| 178 | +4. Hiking data (mixed - demonstrates auto selection) |
| 179 | + |
| 180 | +## Verification |
| 181 | + |
| 182 | +1. **Unit test encoders**: Compare JS output with Python AGON output for test cases |
| 183 | +2. **Visual testing**: Load playground, test each example, verify outputs match docs |
| 184 | +3. **Build check**: `mkdocs build` succeeds without errors |
| 185 | +4. **Live preview**: `mkdocs serve` shows interactive playground |
0 commit comments