feedloop 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.
- feedloop-0.1.0/.claude/settings.local.json +9 -0
- feedloop-0.1.0/.gitignore +19 -0
- feedloop-0.1.0/LICENSE +21 -0
- feedloop-0.1.0/Makefile +18 -0
- feedloop-0.1.0/PKG-INFO +41 -0
- feedloop-0.1.0/PLAN.md +265 -0
- feedloop-0.1.0/README.md +17 -0
- feedloop-0.1.0/demo.py +40 -0
- feedloop-0.1.0/frontend/index.html +12 -0
- feedloop-0.1.0/frontend/package-lock.json +2990 -0
- feedloop-0.1.0/frontend/package.json +23 -0
- feedloop-0.1.0/frontend/src/App.tsx +55 -0
- feedloop-0.1.0/frontend/src/api.ts +49 -0
- feedloop-0.1.0/frontend/src/components/ComparisonView.tsx +62 -0
- feedloop-0.1.0/frontend/src/components/EmptyState.tsx +19 -0
- feedloop-0.1.0/frontend/src/components/ExportPanel.tsx +35 -0
- feedloop-0.1.0/frontend/src/components/FeedbackBar.tsx +32 -0
- feedloop-0.1.0/frontend/src/components/ProgressBar.tsx +19 -0
- feedloop-0.1.0/frontend/src/components/PromptHeader.tsx +12 -0
- feedloop-0.1.0/frontend/src/components/ResponseCard.tsx +17 -0
- feedloop-0.1.0/frontend/src/hooks/useComparison.ts +31 -0
- feedloop-0.1.0/frontend/src/main.tsx +10 -0
- feedloop-0.1.0/frontend/src/styles.css +351 -0
- feedloop-0.1.0/frontend/src/vite-env.d.ts +1 -0
- feedloop-0.1.0/frontend/tsconfig.json +21 -0
- feedloop-0.1.0/frontend/tsconfig.tsbuildinfo +1 -0
- feedloop-0.1.0/frontend/vite.config.ts +15 -0
- feedloop-0.1.0/preferences.jsonl +3 -0
- feedloop-0.1.0/pyproject.toml +43 -0
- feedloop-0.1.0/src/feedloop/__init__.py +155 -0
- feedloop-0.1.0/src/feedloop/__main__.py +44 -0
- feedloop-0.1.0/src/feedloop/_config.py +6 -0
- feedloop-0.1.0/src/feedloop/_db.py +172 -0
- feedloop-0.1.0/src/feedloop/_export.py +30 -0
- feedloop-0.1.0/src/feedloop/_models.py +30 -0
- feedloop-0.1.0/src/feedloop/_routes.py +99 -0
- feedloop-0.1.0/src/feedloop/_server.py +97 -0
- feedloop-0.1.0/src/feedloop/py.typed +0 -0
- feedloop-0.1.0/tests/__init__.py +0 -0
- feedloop-0.1.0/tests/test_db.py +106 -0
- feedloop-0.1.0/tests/test_export.py +64 -0
- feedloop-0.1.0/tests/test_routes.py +111 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.eggs/
|
|
8
|
+
*.egg
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
.env
|
|
12
|
+
*.db
|
|
13
|
+
*.db-wal
|
|
14
|
+
*.db-shm
|
|
15
|
+
node_modules/
|
|
16
|
+
src/feedloop/_static/*
|
|
17
|
+
!src/feedloop/_static/.gitkeep
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.mypy_cache/
|
feedloop-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ram Muthiah
|
|
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.
|
feedloop-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.PHONY: dev-frontend dev-backend build test clean
|
|
2
|
+
|
|
3
|
+
dev-frontend:
|
|
4
|
+
cd frontend && npm run dev
|
|
5
|
+
|
|
6
|
+
dev-backend:
|
|
7
|
+
uvicorn feedloop._server:app --reload
|
|
8
|
+
|
|
9
|
+
build:
|
|
10
|
+
cd frontend && npm run build
|
|
11
|
+
python -m build
|
|
12
|
+
|
|
13
|
+
test:
|
|
14
|
+
pytest tests/ -v
|
|
15
|
+
|
|
16
|
+
clean:
|
|
17
|
+
rm -rf dist/ build/ *.egg-info
|
|
18
|
+
find . -type d -name __pycache__ -exec rm -rf {} +
|
feedloop-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: feedloop
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The fastest way to collect human preference data for LLMs
|
|
5
|
+
Project-URL: Homepage, https://github.com/rammuthiah/feedloop
|
|
6
|
+
Project-URL: Repository, https://github.com/rammuthiah/feedloop
|
|
7
|
+
Author: Ram Muthiah
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: dpo,human-feedback,llm,preference-data,rlhf
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: fastapi>=0.100
|
|
21
|
+
Requires-Dist: pydantic>=2.0
|
|
22
|
+
Requires-Dist: uvicorn[standard]>=0.20
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# feedloop
|
|
26
|
+
|
|
27
|
+
The fastest way to collect human preference data for LLMs.
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import feedloop
|
|
31
|
+
|
|
32
|
+
feedloop.start()
|
|
33
|
+
|
|
34
|
+
feedloop.compare(
|
|
35
|
+
prompt="Explain quantum computing",
|
|
36
|
+
outputs=["Response A", "Response B"],
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Rate in the browser, then export
|
|
40
|
+
feedloop.export("preferences.jsonl")
|
|
41
|
+
```
|
feedloop-0.1.0/PLAN.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# HITL Microservice — Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
AI developers lack a frictionless way to collect human preference data during model iteration. Existing tools are either cloud-heavy (LangSmith, Humanloop), enterprise-scale (Labelbox, Scale AI), or platform-y (Argilla). This project fills the gap: a local-first, pip-installable tool that lets a solo developer go from "bad model output" to "DPO training example" in under a minute.
|
|
6
|
+
|
|
7
|
+
**Positioning:** "The SQLite of human feedback" — zero config, instant value.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Distribution Strategy
|
|
12
|
+
|
|
13
|
+
**Both pip package + open-source GitHub repo.** pip for frictionless install, GitHub for trust and contributions.
|
|
14
|
+
|
|
15
|
+
- Package name: `feedloop` (appears available on PyPI — register early)
|
|
16
|
+
- Import name: `feedloop` regardless of pip name
|
|
17
|
+
- License: MIT
|
|
18
|
+
- Versioning: SemVer, start at `0.1.0`
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Developer's Python script
|
|
26
|
+
│
|
|
27
|
+
│ feedloop.start() → spawns FastAPI in a daemon thread
|
|
28
|
+
│ feedloop.compare(...) → inserts row into SQLite, returns immediately
|
|
29
|
+
│ feedloop.export(...) → reads SQLite, writes JSONL
|
|
30
|
+
│
|
|
31
|
+
┌────▼──────────────────────────────────┐
|
|
32
|
+
│ FastAPI Server (background thread) │
|
|
33
|
+
│ │
|
|
34
|
+
│ GET /api/pending → next comparison │
|
|
35
|
+
│ POST /api/feedback → record choice │
|
|
36
|
+
│ GET /api/stats → progress │
|
|
37
|
+
│ GET /api/export → download JSONL │
|
|
38
|
+
│ GET /* → React static │
|
|
39
|
+
│ │
|
|
40
|
+
│ SQLite (~/.feedloop/feedloop.db, WAL mode) │
|
|
41
|
+
└────┬──────────────────────────────────┘
|
|
42
|
+
│
|
|
43
|
+
┌────▼──────────────────────────────────┐
|
|
44
|
+
│ React UI (static files) │
|
|
45
|
+
│ Polls /api/pending every 1s │
|
|
46
|
+
│ Side-by-side comparison + shortcuts │
|
|
47
|
+
└────────────────────────────────────────┘
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Key design decisions:**
|
|
51
|
+
- Background daemon thread (not subprocess) — shares SQLite, dies when script exits
|
|
52
|
+
- SQLite WAL mode for concurrent reads across threads
|
|
53
|
+
- `atexit` handler for graceful shutdown
|
|
54
|
+
- Position randomization (shuffle A/B) to reduce bias — stored per row for correct export
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Project Structure
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
feedloop/
|
|
62
|
+
├── pyproject.toml
|
|
63
|
+
├── LICENSE (MIT)
|
|
64
|
+
├── README.md
|
|
65
|
+
├── Makefile
|
|
66
|
+
├── src/
|
|
67
|
+
│ └── feedloop/
|
|
68
|
+
│ ├── __init__.py # Public API: start(), compare(), export(), wait(), stop(), status()
|
|
69
|
+
│ ├── __main__.py # python -m feedloop CLI entry
|
|
70
|
+
│ ├── _server.py # FastAPI app + uvicorn background thread
|
|
71
|
+
│ ├── _db.py # SQLite schema, CRUD, WAL mode
|
|
72
|
+
│ ├── _models.py # Pydantic models
|
|
73
|
+
│ ├── _routes.py # API endpoints
|
|
74
|
+
│ ├── _export.py # SQLite → JSONL
|
|
75
|
+
│ ├── _config.py # Defaults (port, db path)
|
|
76
|
+
│ ├── _static/ # React build output (bundled in wheel)
|
|
77
|
+
│ └── py.typed
|
|
78
|
+
├── frontend/
|
|
79
|
+
│ ├── package.json
|
|
80
|
+
│ ├── vite.config.ts # outputs to ../src/feedloop/_static/
|
|
81
|
+
│ ├── tsconfig.json
|
|
82
|
+
│ ├── index.html
|
|
83
|
+
│ └── src/
|
|
84
|
+
│ ├── main.tsx
|
|
85
|
+
│ ├── App.tsx
|
|
86
|
+
│ ├── api.ts
|
|
87
|
+
│ ├── components/
|
|
88
|
+
│ │ ├── ComparisonView.tsx
|
|
89
|
+
│ │ ├── ResponseCard.tsx
|
|
90
|
+
│ │ ├── PromptHeader.tsx
|
|
91
|
+
│ │ ├── FeedbackBar.tsx
|
|
92
|
+
│ │ ├── ProgressBar.tsx
|
|
93
|
+
│ │ ├── ExportPanel.tsx
|
|
94
|
+
│ │ └── EmptyState.tsx
|
|
95
|
+
│ └── hooks/
|
|
96
|
+
│ └── useComparison.ts
|
|
97
|
+
└── tests/
|
|
98
|
+
├── test_db.py
|
|
99
|
+
├── test_routes.py
|
|
100
|
+
├── test_sdk.py
|
|
101
|
+
└── test_export.py
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## SDK API Design
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import feedloop
|
|
110
|
+
|
|
111
|
+
# Launch server + open browser
|
|
112
|
+
feedloop.start(port=7856, db_path=None, open_browser=True)
|
|
113
|
+
|
|
114
|
+
# Submit comparisons (non-blocking)
|
|
115
|
+
cid = feedloop.compare(
|
|
116
|
+
prompt="Explain quantum computing",
|
|
117
|
+
outputs=["Response A text", "Response B text"],
|
|
118
|
+
metadata={"model_a": "gpt-4", "model_b": "claude-3"}
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Optionally block until rated
|
|
122
|
+
result = feedloop.wait(cid, timeout=60)
|
|
123
|
+
|
|
124
|
+
# Check progress
|
|
125
|
+
feedloop.status() # {"pending": 5, "completed": 10, "total": 15}
|
|
126
|
+
|
|
127
|
+
# Export DPO-formatted data
|
|
128
|
+
feedloop.export("preferences.jsonl", session_id=None, format="dpo")
|
|
129
|
+
|
|
130
|
+
# Cleanup
|
|
131
|
+
feedloop.stop()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Example end-to-end usage:**
|
|
135
|
+
```python
|
|
136
|
+
import feedloop
|
|
137
|
+
|
|
138
|
+
feedloop.start()
|
|
139
|
+
|
|
140
|
+
for prompt in test_prompts:
|
|
141
|
+
a = model_a.generate(prompt)
|
|
142
|
+
b = model_b.generate(prompt)
|
|
143
|
+
feedloop.compare(prompt=prompt, outputs=[a, b])
|
|
144
|
+
|
|
145
|
+
input("Rate all comparisons in the browser, then press Enter...")
|
|
146
|
+
feedloop.export("my_preferences.jsonl")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Data Model (SQLite)
|
|
152
|
+
|
|
153
|
+
```sql
|
|
154
|
+
CREATE TABLE comparisons (
|
|
155
|
+
id TEXT PRIMARY KEY, -- UUID
|
|
156
|
+
session_id TEXT NOT NULL,
|
|
157
|
+
prompt TEXT NOT NULL,
|
|
158
|
+
output_a TEXT NOT NULL,
|
|
159
|
+
output_b TEXT NOT NULL,
|
|
160
|
+
display_order TEXT NOT NULL, -- 'ab' or 'ba' (position randomization)
|
|
161
|
+
status TEXT NOT NULL DEFAULT 'pending', -- pending | completed | skipped
|
|
162
|
+
chosen TEXT, -- 'a' | 'b' | NULL
|
|
163
|
+
created_at TEXT NOT NULL,
|
|
164
|
+
completed_at TEXT,
|
|
165
|
+
metadata TEXT -- JSON blob
|
|
166
|
+
);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**DPO export format:**
|
|
170
|
+
```json
|
|
171
|
+
{"prompt": "...", "chosen": "...", "rejected": "..."}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Frontend Design
|
|
177
|
+
|
|
178
|
+
Three states:
|
|
179
|
+
1. **Empty** — "Waiting for comparisons... Run `feedloop.compare()` in your script." (polls every 1s)
|
|
180
|
+
2. **Comparison** — Side-by-side A/B with keyboard shortcuts (`1` = A, `2` = B, `S` = skip), progress bar, markdown rendering
|
|
181
|
+
3. **Done** — Summary stats + download JSONL button
|
|
182
|
+
|
|
183
|
+
Tech: Vite + React + TypeScript, minimal CSS (no Tailwind), `react-markdown` for output rendering.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Build & Packaging
|
|
188
|
+
|
|
189
|
+
- **Build backend:** Hatchling (handles `src/` layout, includes `_static/` in wheel)
|
|
190
|
+
- **Frontend build:** `cd frontend && npm run build` → outputs to `src/feedloop/_static/`
|
|
191
|
+
- **Python build:** `python -m build` → wheel includes static files
|
|
192
|
+
- **Dependencies:** `fastapi>=0.100`, `uvicorn[standard]>=0.20`, `pydantic>=2.0`
|
|
193
|
+
- **Python target:** `>=3.10` (for `X | Y` union syntax)
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Phased Build Order
|
|
198
|
+
|
|
199
|
+
### Phase 1: Foundation
|
|
200
|
+
- [x] `pyproject.toml` + directory structure
|
|
201
|
+
- [x] `_db.py` — SQLite schema, WAL mode, CRUD functions
|
|
202
|
+
- [x] `_models.py` — Pydantic models
|
|
203
|
+
- [x] `tests/test_db.py`
|
|
204
|
+
|
|
205
|
+
### Phase 2: Backend API
|
|
206
|
+
- [x] `_routes.py` — API endpoints
|
|
207
|
+
- [x] `_server.py` — FastAPI app, CORS, static mount
|
|
208
|
+
- [x] `_export.py` — JSONL export
|
|
209
|
+
- [x] `tests/test_routes.py`
|
|
210
|
+
|
|
211
|
+
### Phase 3: SDK
|
|
212
|
+
- [x] `__init__.py` — public API (start, compare, export, wait, stop, status)
|
|
213
|
+
- [x] Background thread server launch
|
|
214
|
+
- [x] `__main__.py` — CLI entry
|
|
215
|
+
- [ ] `tests/test_sdk.py`
|
|
216
|
+
|
|
217
|
+
### Phase 4: Frontend
|
|
218
|
+
- [x] Scaffold Vite + React + TS, configure output path
|
|
219
|
+
- [x] `api.ts` + `useComparison` polling hook
|
|
220
|
+
- [x] ComparisonView, ResponseCard, FeedbackBar components
|
|
221
|
+
- [x] ProgressBar, EmptyState, ExportPanel
|
|
222
|
+
- [x] Keyboard shortcuts + transitions
|
|
223
|
+
- [x] Styling
|
|
224
|
+
|
|
225
|
+
### Phase 5: Integration & Polish
|
|
226
|
+
- [x] Build frontend into `_static/`, verify in wheel
|
|
227
|
+
- [x] End-to-end test: start → compare → rate → export
|
|
228
|
+
- [x] Position randomization (A/B shuffle)
|
|
229
|
+
- [x] README with quickstart
|
|
230
|
+
|
|
231
|
+
### Phase 6: Distribution
|
|
232
|
+
- [ ] TestPyPI upload + fresh venv validation
|
|
233
|
+
- [ ] GitHub repo + MIT license + CI
|
|
234
|
+
- [ ] PyPI publish
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Future Roadmap
|
|
239
|
+
|
|
240
|
+
### v1.1 — Uncertainty-based triggering
|
|
241
|
+
- SDK accepts an `uncertainty` score per comparison
|
|
242
|
+
- Only surfaces comparisons to the human when score exceeds a threshold
|
|
243
|
+
- Aligns with active learning / cost-efficient RLHF
|
|
244
|
+
|
|
245
|
+
### v1.5 — Training loop helpers
|
|
246
|
+
- "Generate training script" button in UI
|
|
247
|
+
- "Re-run prompts with new model" helper
|
|
248
|
+
- Light guidance toward DPO fine-tuning without owning compute
|
|
249
|
+
|
|
250
|
+
### v2.0 — Extended formats
|
|
251
|
+
- Support for >2 outputs (ranking, not just pairwise)
|
|
252
|
+
- Single-output Likert-scale rating (reward model data)
|
|
253
|
+
- Export formats: `anthropic`, `openai`, `trl`
|
|
254
|
+
- WebSocket for real-time updates (replace polling)
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Verification
|
|
259
|
+
|
|
260
|
+
1. `pip install -e .` in a fresh venv
|
|
261
|
+
2. Run `python demo.py` — browser opens, comparisons appear
|
|
262
|
+
3. Rate all comparisons via keyboard shortcuts (`1`, `2`, `S`)
|
|
263
|
+
4. Press Enter — exports to `preferences.jsonl` in DPO format
|
|
264
|
+
5. `python -m build` — verify wheel contains `_static/index.html`
|
|
265
|
+
6. `pip install dist/feedloop-0.1.0-py3-none-any.whl` in clean venv — verify it works
|
feedloop-0.1.0/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# feedloop
|
|
2
|
+
|
|
3
|
+
The fastest way to collect human preference data for LLMs.
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import feedloop
|
|
7
|
+
|
|
8
|
+
feedloop.start()
|
|
9
|
+
|
|
10
|
+
feedloop.compare(
|
|
11
|
+
prompt="Explain quantum computing",
|
|
12
|
+
outputs=["Response A", "Response B"],
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# Rate in the browser, then export
|
|
16
|
+
feedloop.export("preferences.jsonl")
|
|
17
|
+
```
|
feedloop-0.1.0/demo.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Demo script — run this to try feedloop."""
|
|
2
|
+
|
|
3
|
+
import feedloop
|
|
4
|
+
|
|
5
|
+
feedloop.start()
|
|
6
|
+
|
|
7
|
+
# Add some sample comparisons
|
|
8
|
+
feedloop.compare(
|
|
9
|
+
prompt="Explain quantum computing to a 5-year-old",
|
|
10
|
+
outputs=[
|
|
11
|
+
"Quantum computing uses qubits that can be in superposition, meaning they can represent both 0 and 1 simultaneously. This allows quantum computers to process many possibilities at once, making them powerful for certain types of calculations.",
|
|
12
|
+
"Imagine you have a magic coin. A normal coin is either heads or tails. But a magic coin can be both at the same time! A quantum computer uses millions of these magic coins to solve really hard puzzles super fast.",
|
|
13
|
+
],
|
|
14
|
+
metadata={"model_a": "gpt-4", "model_b": "claude-3"},
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
feedloop.compare(
|
|
18
|
+
prompt="Write a haiku about programming",
|
|
19
|
+
outputs=[
|
|
20
|
+
"Lines of code cascade\nSilicon dreams come alive\nBugs hide in the night",
|
|
21
|
+
"Semicolons lost\nThe compiler screams in pain\nStack overflow saves",
|
|
22
|
+
],
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
feedloop.compare(
|
|
26
|
+
prompt="What is the meaning of life?",
|
|
27
|
+
outputs=[
|
|
28
|
+
"The meaning of life is a deeply philosophical question that has been debated for centuries. Different traditions offer different answers — from religious purpose to existentialist self-creation.",
|
|
29
|
+
"42. But seriously, the meaning of life is whatever you decide to make it. Find what brings you joy, help others when you can, and try to leave things better than you found them.",
|
|
30
|
+
],
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
print("\n3 comparisons ready. Rate them in the browser!")
|
|
34
|
+
print("When done, press Enter to export.\n")
|
|
35
|
+
|
|
36
|
+
input()
|
|
37
|
+
|
|
38
|
+
count = feedloop.export("preferences.jsonl")
|
|
39
|
+
print(f"\nExported {count} preferences to preferences.jsonl")
|
|
40
|
+
feedloop.stop()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>feedloop</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|