promptline-opt 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.
- promptline_opt-0.1.0/.claude/settings.local.json +10 -0
- promptline_opt-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +45 -0
- promptline_opt-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- promptline_opt-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +27 -0
- promptline_opt-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +23 -0
- promptline_opt-0.1.0/.github/workflows/ci.yml +103 -0
- promptline_opt-0.1.0/.gitignore +18 -0
- promptline_opt-0.1.0/CHANGELOG.md +47 -0
- promptline_opt-0.1.0/CODE_OF_CONDUCT.md +47 -0
- promptline_opt-0.1.0/CONTRIBUTING.md +42 -0
- promptline_opt-0.1.0/LICENSE +21 -0
- promptline_opt-0.1.0/Makefile +39 -0
- promptline_opt-0.1.0/PKG-INFO +244 -0
- promptline_opt-0.1.0/README.md +215 -0
- promptline_opt-0.1.0/SECURITY.md +32 -0
- promptline_opt-0.1.0/docs/concepts/core.md +60 -0
- promptline_opt-0.1.0/docs/concepts/gate.md +48 -0
- promptline_opt-0.1.0/docs/concepts/judge.md +52 -0
- promptline_opt-0.1.0/docs/concepts/optimizers.md +58 -0
- promptline_opt-0.1.0/docs/concepts/serving.md +55 -0
- promptline_opt-0.1.0/docs/superpowers/plans/2026-07-03-promptline-implementation.md +314 -0
- promptline_opt-0.1.0/docs/superpowers/specs/2026-07-03-promptline-design.md +180 -0
- promptline_opt-0.1.0/examples/support-assistant/README.md +145 -0
- promptline_opt-0.1.0/examples/support-assistant/fixtures/gold_fixture.jsonl +50 -0
- promptline_opt-0.1.0/examples/support-assistant/fixtures/support_fixture.jsonl +60 -0
- promptline_opt-0.1.0/promptline/__init__.py +1 -0
- promptline_opt-0.1.0/promptline/cli/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/cli/demo.py +235 -0
- promptline_opt-0.1.0/promptline/cli/main.py +1083 -0
- promptline_opt-0.1.0/promptline/core/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/core/cache.py +56 -0
- promptline_opt-0.1.0/promptline/core/config.py +159 -0
- promptline_opt-0.1.0/promptline/core/llm.py +63 -0
- promptline_opt-0.1.0/promptline/core/openrouter.py +148 -0
- promptline_opt-0.1.0/promptline/core/program.py +242 -0
- promptline_opt-0.1.0/promptline/core/types.py +84 -0
- promptline_opt-0.1.0/promptline/data/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/data/dataset.py +160 -0
- promptline_opt-0.1.0/promptline/data/loaders.py +193 -0
- promptline_opt-0.1.0/promptline/eval/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/eval/harness.py +263 -0
- promptline_opt-0.1.0/promptline/eval/stats.py +140 -0
- promptline_opt-0.1.0/promptline/judge/__init__.py +19 -0
- promptline_opt-0.1.0/promptline/judge/calibrator.py +269 -0
- promptline_opt-0.1.0/promptline/judge/judge.py +366 -0
- promptline_opt-0.1.0/promptline/judge/metric_factory.py +95 -0
- promptline_opt-0.1.0/promptline/judge/metrics.py +101 -0
- promptline_opt-0.1.0/promptline/optimizers/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/optimizers/base.py +185 -0
- promptline_opt-0.1.0/promptline/optimizers/bootstrap.py +410 -0
- promptline_opt-0.1.0/promptline/optimizers/gepa/__init__.py +5 -0
- promptline_opt-0.1.0/promptline/optimizers/gepa/engine.py +588 -0
- promptline_opt-0.1.0/promptline/optimizers/gepa/merge.py +100 -0
- promptline_opt-0.1.0/promptline/optimizers/gepa/pareto.py +66 -0
- promptline_opt-0.1.0/promptline/optimizers/gepa/reflect.py +72 -0
- promptline_opt-0.1.0/promptline/optimizers/gepa/state.py +85 -0
- promptline_opt-0.1.0/promptline/optimizers/mipro.py +515 -0
- promptline_opt-0.1.0/promptline/optimizers/opro.py +293 -0
- promptline_opt-0.1.0/promptline/optimizers/protegi.py +461 -0
- promptline_opt-0.1.0/promptline/registry/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/registry/gate.py +350 -0
- promptline_opt-0.1.0/promptline/registry/registry.py +252 -0
- promptline_opt-0.1.0/promptline/server/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/server/app.py +287 -0
- promptline_opt-0.1.0/promptline/server/runs.py +118 -0
- promptline_opt-0.1.0/promptline/tui/__init__.py +0 -0
- promptline_opt-0.1.0/promptline/tui/app.py +341 -0
- promptline_opt-0.1.0/promptline/tui/events.py +138 -0
- promptline_opt-0.1.0/pyproject.toml +64 -0
- promptline_opt-0.1.0/ruff.toml +6 -0
- promptline_opt-0.1.0/tests/__init__.py +0 -0
- promptline_opt-0.1.0/tests/cli/__init__.py +0 -0
- promptline_opt-0.1.0/tests/cli/test_cli.py +1294 -0
- promptline_opt-0.1.0/tests/cli/test_demo.py +103 -0
- promptline_opt-0.1.0/tests/core/__init__.py +0 -0
- promptline_opt-0.1.0/tests/core/test_cache.py +66 -0
- promptline_opt-0.1.0/tests/core/test_llm.py +65 -0
- promptline_opt-0.1.0/tests/core/test_openrouter.py +269 -0
- promptline_opt-0.1.0/tests/core/test_program.py +315 -0
- promptline_opt-0.1.0/tests/core/test_types.py +119 -0
- promptline_opt-0.1.0/tests/data/__init__.py +0 -0
- promptline_opt-0.1.0/tests/data/test_dataset.py +255 -0
- promptline_opt-0.1.0/tests/data/test_loaders.py +224 -0
- promptline_opt-0.1.0/tests/e2e/__init__.py +0 -0
- promptline_opt-0.1.0/tests/e2e/conftest.py +203 -0
- promptline_opt-0.1.0/tests/e2e/serve_fixture.py +124 -0
- promptline_opt-0.1.0/tests/e2e/test_cli_e2e.py +223 -0
- promptline_opt-0.1.0/tests/e2e/test_failure_paths.py +254 -0
- promptline_opt-0.1.0/tests/e2e/test_full_pipeline_offline.py +227 -0
- promptline_opt-0.1.0/tests/eval/__init__.py +0 -0
- promptline_opt-0.1.0/tests/eval/test_harness.py +446 -0
- promptline_opt-0.1.0/tests/eval/test_stats.py +169 -0
- promptline_opt-0.1.0/tests/integration/__init__.py +0 -0
- promptline_opt-0.1.0/tests/integration/test_live_smoke.py +133 -0
- promptline_opt-0.1.0/tests/judge/__init__.py +0 -0
- promptline_opt-0.1.0/tests/judge/test_calibrator.py +330 -0
- promptline_opt-0.1.0/tests/judge/test_judge.py +277 -0
- promptline_opt-0.1.0/tests/judge/test_metric_factory.py +133 -0
- promptline_opt-0.1.0/tests/judge/test_metrics.py +109 -0
- promptline_opt-0.1.0/tests/optimizers/__init__.py +0 -0
- promptline_opt-0.1.0/tests/optimizers/gepa/__init__.py +0 -0
- promptline_opt-0.1.0/tests/optimizers/gepa/test_engine.py +564 -0
- promptline_opt-0.1.0/tests/optimizers/gepa/test_pareto.py +148 -0
- promptline_opt-0.1.0/tests/optimizers/gepa/test_reflect_merge.py +205 -0
- promptline_opt-0.1.0/tests/optimizers/test_base.py +185 -0
- promptline_opt-0.1.0/tests/optimizers/test_bootstrap.py +625 -0
- promptline_opt-0.1.0/tests/optimizers/test_event_payloads.py +203 -0
- promptline_opt-0.1.0/tests/optimizers/test_mipro.py +432 -0
- promptline_opt-0.1.0/tests/optimizers/test_opro.py +310 -0
- promptline_opt-0.1.0/tests/optimizers/test_protegi.py +366 -0
- promptline_opt-0.1.0/tests/registry/__init__.py +0 -0
- promptline_opt-0.1.0/tests/registry/test_gate.py +419 -0
- promptline_opt-0.1.0/tests/registry/test_registry.py +205 -0
- promptline_opt-0.1.0/tests/server/__init__.py +0 -0
- promptline_opt-0.1.0/tests/server/test_api.py +689 -0
- promptline_opt-0.1.0/tests/test_import.py +26 -0
- promptline_opt-0.1.0/tests/tui/__init__.py +0 -0
- promptline_opt-0.1.0/tests/tui/test_tui.py +251 -0
- promptline_opt-0.1.0/uv.lock +2326 -0
- promptline_opt-0.1.0/web/.gitignore +6 -0
- promptline_opt-0.1.0/web/README.md +63 -0
- promptline_opt-0.1.0/web/e2e/dashboard.spec.ts +100 -0
- promptline_opt-0.1.0/web/index.html +12 -0
- promptline_opt-0.1.0/web/package-lock.json +3444 -0
- promptline_opt-0.1.0/web/package.json +32 -0
- promptline_opt-0.1.0/web/playwright.config.ts +33 -0
- promptline_opt-0.1.0/web/src/Layout.tsx +35 -0
- promptline_opt-0.1.0/web/src/__tests__/DiffView.test.tsx +24 -0
- promptline_opt-0.1.0/web/src/__tests__/lineage.test.ts +63 -0
- promptline_opt-0.1.0/web/src/__tests__/runReducer.test.ts +114 -0
- promptline_opt-0.1.0/web/src/api.ts +191 -0
- promptline_opt-0.1.0/web/src/components/DiffView.tsx +23 -0
- promptline_opt-0.1.0/web/src/components/Panel.tsx +10 -0
- promptline_opt-0.1.0/web/src/components/ScoreCurve.tsx +85 -0
- promptline_opt-0.1.0/web/src/main.tsx +35 -0
- promptline_opt-0.1.0/web/src/pages/GatePage.tsx +239 -0
- promptline_opt-0.1.0/web/src/pages/JudgePage.tsx +108 -0
- promptline_opt-0.1.0/web/src/pages/LineagePage.tsx +166 -0
- promptline_opt-0.1.0/web/src/pages/RegistryPage.tsx +164 -0
- promptline_opt-0.1.0/web/src/pages/RunDetail.tsx +154 -0
- promptline_opt-0.1.0/web/src/pages/RunsPage.tsx +130 -0
- promptline_opt-0.1.0/web/src/state/lineage.ts +84 -0
- promptline_opt-0.1.0/web/src/state/runReducer.ts +186 -0
- promptline_opt-0.1.0/web/src/test-setup.ts +1 -0
- promptline_opt-0.1.0/web/src/theme.css +466 -0
- promptline_opt-0.1.0/web/tsconfig.app.json +21 -0
- promptline_opt-0.1.0/web/tsconfig.app.tsbuildinfo +1 -0
- promptline_opt-0.1.0/web/tsconfig.json +7 -0
- promptline_opt-0.1.0/web/tsconfig.node.json +15 -0
- promptline_opt-0.1.0/web/tsconfig.node.tsbuildinfo +1 -0
- promptline_opt-0.1.0/web/vite.config.ts +25 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report something that isn't working as expected
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: Thanks for taking the time to file a bug. Please fill in the sections below.
|
|
8
|
+
- type: textarea
|
|
9
|
+
id: what-happened
|
|
10
|
+
attributes:
|
|
11
|
+
label: What happened?
|
|
12
|
+
description: A clear description of the bug, and what you expected instead.
|
|
13
|
+
placeholder: When I run `promptline optimize ...`, it ...
|
|
14
|
+
validations:
|
|
15
|
+
required: true
|
|
16
|
+
- type: textarea
|
|
17
|
+
id: repro
|
|
18
|
+
attributes:
|
|
19
|
+
label: Steps to reproduce
|
|
20
|
+
description: Ideally the exact commands. A `PROMPTLINE_FAKE_SCRIPT` repro that needs no API key is ideal.
|
|
21
|
+
placeholder: |
|
|
22
|
+
1. promptline init
|
|
23
|
+
2. promptline optimize --optimizer gepa ...
|
|
24
|
+
3. ...
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: logs
|
|
29
|
+
attributes:
|
|
30
|
+
label: Relevant output / traceback
|
|
31
|
+
render: shell
|
|
32
|
+
- type: input
|
|
33
|
+
id: version
|
|
34
|
+
attributes:
|
|
35
|
+
label: Promptline version
|
|
36
|
+
description: Output of `promptline --version`
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
- type: input
|
|
40
|
+
id: environment
|
|
41
|
+
attributes:
|
|
42
|
+
label: Environment
|
|
43
|
+
description: OS, Python version, install method (pip / editable / clone)
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an idea or enhancement
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: Problem / motivation
|
|
9
|
+
description: What are you trying to do that Promptline doesn't support today?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposal
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed solution
|
|
16
|
+
description: What would you like to see? (A new optimizer, a config option, an API endpoint, etc.)
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: alternatives
|
|
21
|
+
attributes:
|
|
22
|
+
label: Alternatives considered
|
|
23
|
+
- type: textarea
|
|
24
|
+
id: context
|
|
25
|
+
attributes:
|
|
26
|
+
label: Additional context
|
|
27
|
+
description: Links to papers, related tools, or prior art.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!-- Thanks for contributing to Promptline! -->
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
<!-- What does this PR change and why? -->
|
|
6
|
+
|
|
7
|
+
## Related issues
|
|
8
|
+
|
|
9
|
+
<!-- e.g. Closes #123 -->
|
|
10
|
+
|
|
11
|
+
## Changes
|
|
12
|
+
|
|
13
|
+
<!-- Bullet the notable changes. -->
|
|
14
|
+
-
|
|
15
|
+
|
|
16
|
+
## Checklist
|
|
17
|
+
|
|
18
|
+
- [ ] `uv run pytest -q` passes
|
|
19
|
+
- [ ] `uv run ruff check .` and `uv run ruff format --check .` pass
|
|
20
|
+
- [ ] `uv run pyright promptline` is clean
|
|
21
|
+
- [ ] Tests added/updated for the change (TDD; `FakeLLMClient` — no live LLM calls in unit tests)
|
|
22
|
+
- [ ] Docs updated if behavior/CLI/API changed (`README.md`, `docs/concepts/`)
|
|
23
|
+
- [ ] For web changes: `cd web && npm test && npm run build` pass
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
python:
|
|
15
|
+
name: python ${{ matrix.python-version }}
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.11", "3.12"]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v5
|
|
26
|
+
with:
|
|
27
|
+
enable-cache: true
|
|
28
|
+
|
|
29
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
30
|
+
run: uv python install ${{ matrix.python-version }}
|
|
31
|
+
|
|
32
|
+
- name: Sync dependencies
|
|
33
|
+
run: uv sync --all-extras --dev
|
|
34
|
+
|
|
35
|
+
- name: Ruff lint
|
|
36
|
+
run: uv run ruff check .
|
|
37
|
+
|
|
38
|
+
- name: Ruff format check
|
|
39
|
+
run: uv run ruff format --check .
|
|
40
|
+
|
|
41
|
+
- name: Pyright
|
|
42
|
+
run: uv run pyright promptline
|
|
43
|
+
|
|
44
|
+
- name: Pytest (offline suite)
|
|
45
|
+
run: uv run pytest -q
|
|
46
|
+
|
|
47
|
+
web:
|
|
48
|
+
name: web (vitest + build)
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
defaults:
|
|
51
|
+
run:
|
|
52
|
+
working-directory: web
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- uses: actions/setup-node@v4
|
|
57
|
+
with:
|
|
58
|
+
node-version: "20"
|
|
59
|
+
cache: npm
|
|
60
|
+
cache-dependency-path: web/package-lock.json
|
|
61
|
+
|
|
62
|
+
- name: Install dependencies
|
|
63
|
+
run: npm ci
|
|
64
|
+
|
|
65
|
+
- name: Unit tests
|
|
66
|
+
run: npm test
|
|
67
|
+
|
|
68
|
+
- name: Production build
|
|
69
|
+
run: npm run build
|
|
70
|
+
|
|
71
|
+
dashboard-e2e:
|
|
72
|
+
name: dashboard e2e (playwright)
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@v4
|
|
76
|
+
|
|
77
|
+
- name: Install uv
|
|
78
|
+
uses: astral-sh/setup-uv@v5
|
|
79
|
+
with:
|
|
80
|
+
enable-cache: true
|
|
81
|
+
|
|
82
|
+
- name: Sync Python dependencies
|
|
83
|
+
run: uv sync --all-extras --dev
|
|
84
|
+
|
|
85
|
+
- uses: actions/setup-node@v4
|
|
86
|
+
with:
|
|
87
|
+
node-version: "20"
|
|
88
|
+
cache: npm
|
|
89
|
+
cache-dependency-path: web/package-lock.json
|
|
90
|
+
|
|
91
|
+
- name: Install web dependencies and build
|
|
92
|
+
working-directory: web
|
|
93
|
+
run: |
|
|
94
|
+
npm ci
|
|
95
|
+
npm run build
|
|
96
|
+
|
|
97
|
+
- name: Install Playwright browser
|
|
98
|
+
working-directory: web
|
|
99
|
+
run: npx playwright install --with-deps chromium
|
|
100
|
+
|
|
101
|
+
- name: Run dashboard e2e
|
|
102
|
+
working-directory: web
|
|
103
|
+
run: npm run e2e
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
runs/
|
|
3
|
+
.promptline/
|
|
4
|
+
node_modules/
|
|
5
|
+
web/dist/
|
|
6
|
+
__pycache__/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
*.pyc
|
|
9
|
+
*.egg-info/
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
.DS_Store
|
|
13
|
+
promptline.yaml
|
|
14
|
+
|
|
15
|
+
# Playwright
|
|
16
|
+
web/test-results/
|
|
17
|
+
web/playwright-report/
|
|
18
|
+
web/.playwright/
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] — 2026-07-06
|
|
10
|
+
|
|
11
|
+
Initial release. The full `calibrate → optimize → gate → serve` pipeline.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Core library**: declarative signatures/programs with per-module trace
|
|
16
|
+
recording, an `LLMClient` protocol with an OpenRouter adapter (BYO key, pooled
|
|
17
|
+
connections, retries with backoff, per-call cost tracking), a SQLite call
|
|
18
|
+
cache, and an eval harness with hard rollout/cost budget walls.
|
|
19
|
+
- **Optimizers (from scratch, one contract)**: GEPA (per-instance Pareto
|
|
20
|
+
selection, reflective mutation, system-aware merge, resumable checkpoints),
|
|
21
|
+
MIPRO (bootstrap demos → grounded instruction proposals → TPE search),
|
|
22
|
+
BootstrapFewShot (+ random search), ProTeGi (textual gradients + CAPO-style
|
|
23
|
+
racing), and OPRO.
|
|
24
|
+
- **Judge subsystem**: pointwise and pairwise rubric judges (CoT-before-verdict,
|
|
25
|
+
anti-verbosity, position-swap debiasing, k-sampling), agreement metrics
|
|
26
|
+
(Cohen's κ, Spearman, pairwise accuracy), a calibrator that certifies the judge
|
|
27
|
+
against human labels, and meta-optimization of the judge prompt. The calibrated
|
|
28
|
+
judge is the default optimization/gate metric, and a passing certificate is
|
|
29
|
+
required to optimize.
|
|
30
|
+
- **Statistical deploy gate**: paired bootstrap CIs, Holm correction across
|
|
31
|
+
candidates, independent validation-split confirmation, verbosity tripwires, and
|
|
32
|
+
refusals for uncalibrated judges, undersized splits, and dev/val contamination.
|
|
33
|
+
- **Registry & serving**: SQLite-backed versioned prompt registry with lineage,
|
|
34
|
+
an active pointer only the gate advances, rollback, and a FastAPI serving plane
|
|
35
|
+
(`GET /prompts/{program}/active` with ETag) plus a control plane with SSE run
|
|
36
|
+
streaming.
|
|
37
|
+
- **Interfaces**: a Typer CLI, a Textual TUI cockpit, and a React + Vite
|
|
38
|
+
dashboard (Runs, Lineage, Judge, Gate, Registry) served statically by FastAPI.
|
|
39
|
+
- **Data**: JSONL schema + adapters, and loaders for HelpSteer2, Bitext, and
|
|
40
|
+
MT-Bench human judgments.
|
|
41
|
+
- **Demo**: `promptline demo setup` (online and `--offline`) for the
|
|
42
|
+
support-assistant walkthrough.
|
|
43
|
+
- **Tests**: 444 offline unit/integration tests, an offline end-to-end suite,
|
|
44
|
+
Playwright dashboard e2e, and an opt-in live smoke test.
|
|
45
|
+
|
|
46
|
+
[Unreleased]: https://github.com/sanskarpan/promptline/compare/v0.1.0...HEAD
|
|
47
|
+
[0.1.0]: https://github.com/sanskarpan/promptline/releases/tag/v0.1.0
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
+
orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment:
|
|
18
|
+
|
|
19
|
+
- Demonstrating empathy and kindness toward other people
|
|
20
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
21
|
+
- Giving and gracefully accepting constructive feedback
|
|
22
|
+
- Accepting responsibility and apologizing to those affected by our mistakes
|
|
23
|
+
- Focusing on what is best for the overall community
|
|
24
|
+
|
|
25
|
+
Examples of unacceptable behavior:
|
|
26
|
+
|
|
27
|
+
- The use of sexualized language or imagery, and sexual attention or advances
|
|
28
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
29
|
+
- Public or private harassment
|
|
30
|
+
- Publishing others' private information without explicit permission
|
|
31
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
+
professional setting
|
|
33
|
+
|
|
34
|
+
## Enforcement
|
|
35
|
+
|
|
36
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
37
|
+
reported to the project maintainer. All complaints will be reviewed and
|
|
38
|
+
investigated promptly and fairly. The maintainer is obligated to respect the
|
|
39
|
+
privacy and security of the reporter of any incident.
|
|
40
|
+
|
|
41
|
+
## Attribution
|
|
42
|
+
|
|
43
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
44
|
+
version 2.1, available at
|
|
45
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
46
|
+
|
|
47
|
+
[homepage]: https://www.contributor-covenant.org
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Contributing to Promptline
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
uv sync # Python 3.11+, installs promptline + dev deps
|
|
7
|
+
cd web && npm install # only needed for dashboard work
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Test tiers
|
|
11
|
+
|
|
12
|
+
| Tier | Command | Needs | When |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| Offline suite (unit + e2e) | `make test` (`uv run pytest -q`) | nothing | every change |
|
|
15
|
+
| Dashboard e2e | `make e2e` | `npm run build` in `web/` + `npx playwright install chromium` | dashboard changes |
|
|
16
|
+
| Live smoke | `make live-smoke` | `OPENROUTER_API_KEY` (< $0.50) | before releases / adapter changes |
|
|
17
|
+
|
|
18
|
+
The offline suite is the gate for merging; the live tier is opt-in and marked
|
|
19
|
+
`@pytest.mark.live` (auto-skipped without a key). Lint with `make lint`.
|
|
20
|
+
|
|
21
|
+
## The fake-script pattern
|
|
22
|
+
|
|
23
|
+
Tests never hit a real LLM. Two mechanisms:
|
|
24
|
+
|
|
25
|
+
1. **In Python** — `FakeLLMClient(script=...)` accepts a list of canned
|
|
26
|
+
responses or a callable `(LLMCall) -> str`. The canonical e2e trick
|
|
27
|
+
(see `tests/e2e/conftest.py`): the client answers with a marker string
|
|
28
|
+
iff the system prompt already contains it, while scripted
|
|
29
|
+
reflection/proposal calls return an instruction that *adds* the marker —
|
|
30
|
+
so a metric that rewards the marker makes optimizers genuinely "improve".
|
|
31
|
+
2. **Through the CLI** — set `PROMPTLINE_FAKE_SCRIPT=/path/to/script.json`.
|
|
32
|
+
The JSON holds a cycling `"responses": [...]` list and/or first-match
|
|
33
|
+
`"keyed": [{"contains": ..., "response": ...}]` rules matched against the
|
|
34
|
+
full prompt text. See `tests/e2e/test_cli_e2e.py` for a complete
|
|
35
|
+
init → calibrate → optimize → gate → serve chain driven this way.
|
|
36
|
+
|
|
37
|
+
## Conventions
|
|
38
|
+
|
|
39
|
+
- Conventional commits (`feat:`, `fix:`, `test:`, `docs:` …).
|
|
40
|
+
- `uv run ruff check .` must pass; keep new tests deterministic (seeded RNG,
|
|
41
|
+
scripted clients, tmp_path workspaces).
|
|
42
|
+
- Prefer composing real components in tests and faking only the LLM.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sanskar Pandey
|
|
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,39 @@
|
|
|
1
|
+
.PHONY: help install test e2e live-smoke lint format format-check typecheck check web-test web-build build
|
|
2
|
+
|
|
3
|
+
help: ## Show this help
|
|
4
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}'
|
|
5
|
+
|
|
6
|
+
install: ## Sync all dependencies (runtime + data extra + dev)
|
|
7
|
+
uv sync --all-extras --dev
|
|
8
|
+
|
|
9
|
+
test: ## Offline test suite (fast, no network, no API key)
|
|
10
|
+
uv run pytest -q
|
|
11
|
+
|
|
12
|
+
lint: ## Ruff lint
|
|
13
|
+
uv run ruff check .
|
|
14
|
+
|
|
15
|
+
format: ## Apply Ruff formatting
|
|
16
|
+
uv run ruff format .
|
|
17
|
+
|
|
18
|
+
format-check: ## Check Ruff formatting without writing
|
|
19
|
+
uv run ruff format --check .
|
|
20
|
+
|
|
21
|
+
typecheck: ## Pyright type check
|
|
22
|
+
uv run pyright promptline
|
|
23
|
+
|
|
24
|
+
check: lint format-check typecheck test ## Run the full local gate (matches CI python job)
|
|
25
|
+
|
|
26
|
+
web-test: ## Dashboard unit tests (vitest)
|
|
27
|
+
cd web && npm test
|
|
28
|
+
|
|
29
|
+
web-build: ## Build the dashboard (writes web/dist)
|
|
30
|
+
cd web && npm run build
|
|
31
|
+
|
|
32
|
+
e2e: ## Dashboard Playwright e2e (needs web-build + chromium; see web/README.md)
|
|
33
|
+
cd web && npm run e2e
|
|
34
|
+
|
|
35
|
+
live-smoke: ## Opt-in live smoke against OpenRouter (needs OPENROUTER_API_KEY; ~<$0.50)
|
|
36
|
+
uv run pytest -m live tests/integration -q
|
|
37
|
+
|
|
38
|
+
build: ## Build the sdist + wheel
|
|
39
|
+
uv build
|