programasweights 0.2.8__tar.gz → 0.3.1__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.
- {programasweights-0.2.8 → programasweights-0.3.1}/AGENTS.md +25 -4
- {programasweights-0.2.8 → programasweights-0.3.1}/PKG-INFO +17 -14
- {programasweights-0.2.8 → programasweights-0.3.1}/PYPI_README.md +16 -13
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/index.md +2 -2
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/__init__.py +73 -16
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/client.py +14 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/pyproject.toml +1 -1
- {programasweights-0.2.8 → programasweights-0.3.1}/.gitignore +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/.readthedocs.yaml +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/CHANGELOG.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/LICENSE +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/README.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/adr/001-llama-cpp-over-pytorch.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/adr/002-q4_0-adapter-format.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/adr/003-single-spec-field.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/adr/004-compiler-naming.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/adr/005-vllm-hidden-states.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/adr/006-email-api-key-auth.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/advanced/adrs.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/advanced/architecture.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/api-reference/cli.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/api-reference/python-sdk.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/api-reference/rest-api.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/architecture.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/case-studies/log-monitoring.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/case-studies/semantic-search.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/case-studies/site-navigation.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/case-studies/tool-calling.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/getting-started/first-program.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/getting-started/installation.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/getting-started/naming-programs.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/guide/browser-inference.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/guide/how-it-works.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/guide/local-inference.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/guide/writing-good-specs.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/hub/browsing-programs.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/hub/feedback-cases.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/hub/publishing-programs.md +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/docs/requirements.txt +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/examples/flask_app.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/examples/jupyter_notebook.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/examples/langchain_integration.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/examples/paw_monitor.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/examples/replace_openai.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/mkdocs.yml +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/_output.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/artifacts.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/cache.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/cli.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/compiler/__init__.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/compiler/dummy.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/config.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/convert_peft_to_paw.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/paw_format.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/runtime/__init__.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/runtime/interpreter.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/runtime/interpreter_onnx.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/programasweights/runtime_llamacpp.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/tests/test_offline_cache.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/tests/test_sdk.py +0 -0
- {programasweights-0.2.8 → programasweights-0.3.1}/tests/test_sdk.sh +0 -0
|
@@ -20,7 +20,7 @@ import programasweights as paw
|
|
|
20
20
|
# "email-triage" is an official pre-compiled program (slug)
|
|
21
21
|
fn = paw.function("email-triage")
|
|
22
22
|
fn("Urgent: server is down!") # "immediate"
|
|
23
|
-
fn("Newsletter: spring picnic") # "
|
|
23
|
+
fn("Newsletter: spring picnic") # "wait"
|
|
24
24
|
|
|
25
25
|
# Compile your own from a description
|
|
26
26
|
program = paw.compile(
|
|
@@ -28,7 +28,7 @@ program = paw.compile(
|
|
|
28
28
|
compiler="paw-4b-qwen3-0.6b" # or "paw-4b-gpt2" for smaller/faster
|
|
29
29
|
)
|
|
30
30
|
fn = paw.function(program.id)
|
|
31
|
-
fn("{name: 'Alice',}") # '{"name":
|
|
31
|
+
fn("{name: 'Alice',}") # '{"name":"Alice"}'
|
|
32
32
|
|
|
33
33
|
# Or compile and load in one step
|
|
34
34
|
fn = paw.compile_and_load("Classify sentiment as positive or negative")
|
|
@@ -161,6 +161,22 @@ Generate API keys at https://programasweights.com/settings.
|
|
|
161
161
|
|
|
162
162
|
Commands: `paw compile --spec "..." --json`, `paw run --program <id> --input "..."`, `paw info <id>`, `paw rename <id> <slug>`, `paw login`. All support `--json` for structured output.
|
|
163
163
|
|
|
164
|
+
## Versioning
|
|
165
|
+
|
|
166
|
+
Slugs support version history. Recompiling with the same slug creates a new version:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
p1 = paw.compile("Count words v1", slug="word-counter") # v1
|
|
170
|
+
p2 = paw.compile("Count words v2", slug="word-counter") # v2 (auto-bumps)
|
|
171
|
+
|
|
172
|
+
fn = paw.function("da03/word-counter") # resolves to main (latest)
|
|
173
|
+
fn = paw.function("da03/word-counter@v1") # pinned to v1
|
|
174
|
+
|
|
175
|
+
versions = paw.list_versions("da03/word-counter") # all versions
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Pinned versions (`@v1`) are immutable and cached locally forever. Bare slugs always check the server for the latest main version (falls back to cache if offline).
|
|
179
|
+
|
|
164
180
|
## Full API Reference
|
|
165
181
|
|
|
166
182
|
```python
|
|
@@ -170,16 +186,19 @@ program = paw.compile(
|
|
|
170
186
|
slug=None, # URL-safe handle (requires auth)
|
|
171
187
|
public=True, # list on public hub
|
|
172
188
|
)
|
|
173
|
-
# Returns: Program(id, slug, status, timings, error)
|
|
189
|
+
# Returns: Program(id, slug, status, version, version_action, timings, error)
|
|
174
190
|
|
|
175
191
|
fn = paw.function(program) # accepts Program object, hash ID, or slug
|
|
176
192
|
fn = paw.function("a6b454023d41ac9ca845")
|
|
177
193
|
fn = paw.function("da03/my-classifier")
|
|
194
|
+
fn = paw.function("da03/my-classifier@v2") # pinned version
|
|
195
|
+
fn = paw.function("da03/my-classifier", offline=True) # skip server check
|
|
178
196
|
|
|
179
197
|
result: str = fn(input_text: str, max_tokens=None, temperature=0.0)
|
|
180
198
|
|
|
181
199
|
fn = paw.compile_and_load(spec, compiler="paw-4b-qwen3-0.6b")
|
|
182
200
|
|
|
201
|
+
versions = paw.list_versions("da03/my-classifier") # version history
|
|
183
202
|
programs = paw.list_programs(sort="recent", per_page=20) # requires auth
|
|
184
203
|
|
|
185
204
|
paw.login()
|
|
@@ -192,10 +211,12 @@ paw.login()
|
|
|
192
211
|
| `RuntimeError: assets not ready` on download | Program still generating after compile | SDK polls automatically for up to 30s. If persistent, recompile. |
|
|
193
212
|
| `httpx.HTTPStatusError: 422` on compile | Spec too short (<10 chars) | Adjust spec length. |
|
|
194
213
|
| `httpx.HTTPStatusError: 429` | Rate limit exceeded | Wait, or sign in for higher limits. |
|
|
214
|
+
| GPU/Metal errors on load | GPU backend not available or incompatible | Set `PAW_GPU_LAYERS=0` or pass `n_gpu_layers=0` to force CPU. |
|
|
195
215
|
|
|
196
216
|
## Performance
|
|
197
217
|
|
|
198
|
-
- **
|
|
218
|
+
- **GPU acceleration** enabled by default (`n_gpu_layers=-1`). Uses Metal on Mac, CUDA on Linux, falls back to CPU automatically. If GPU causes issues, set `PAW_GPU_LAYERS=0` or pass `n_gpu_layers=0`.
|
|
219
|
+
- **First call** ~1-5s (loads base model). Subsequent calls ~0.05-0.5s depending on input length and GPU availability.
|
|
199
220
|
- **Base model shared** across functions on disk. Each LoRA adapter adds ~22 MB.
|
|
200
221
|
- **Cache**: `~/.cache/programasweights/`. Override with `PAW_CACHE_DIR`.
|
|
201
222
|
- **Offline** after first download.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: programasweights
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Compile natural language specifications into neural programs that run locally via llama.cpp.
|
|
5
5
|
Project-URL: Homepage, https://programasweights.com
|
|
6
6
|
Project-URL: Repository, https://github.com/programasweights/programasweights-python
|
|
@@ -48,7 +48,7 @@ import programasweights as paw
|
|
|
48
48
|
# Use a pre-compiled function (downloads once, runs locally forever)
|
|
49
49
|
fn = paw.function("email-triage")
|
|
50
50
|
fn("Urgent: the server is down!") # "immediate"
|
|
51
|
-
fn("Newsletter: spring picnic") # "
|
|
51
|
+
fn("Newsletter: spring picnic") # "wait"
|
|
52
52
|
|
|
53
53
|
# Compile your own from a description
|
|
54
54
|
program = paw.compile(
|
|
@@ -57,7 +57,7 @@ program = paw.compile(
|
|
|
57
57
|
slug="json-fixer" # optional: creates username/json-fixer handle
|
|
58
58
|
)
|
|
59
59
|
fn = paw.function(program.slug) # or paw.function(program.id)
|
|
60
|
-
fn("{name: 'Alice',}") # '{"name":
|
|
60
|
+
fn("{name: 'Alice',}") # '{"name":"Alice"}'
|
|
61
61
|
|
|
62
62
|
# Or compile and load in one step
|
|
63
63
|
fn = paw.compile_and_load("Classify sentiment as positive or negative")
|
|
@@ -66,17 +66,20 @@ fn("I love this!") # "positive"
|
|
|
66
66
|
|
|
67
67
|
## Two Compilers
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
69
|
+
|
|
70
|
+
| | Standard (Qwen3 0.6B) | Compact (GPT-2 124M) |
|
|
71
|
+
| --------------- | --------------------- | -------------------- |
|
|
72
|
+
| Compiler name | `paw-4b-qwen3-0.6b` | `paw-4b-gpt2` |
|
|
73
|
+
| Accuracy | Higher | Lower |
|
|
74
|
+
| Base model size | 594 MB | 105 MB |
|
|
75
|
+
| Program size | ~22 MB | ~5 MB |
|
|
76
|
+
| Local inference | ~0.05-0.5s per call | ~0.03-0.3s per call |
|
|
77
|
+
| Runs in browser | No | Yes (WebAssembly) |
|
|
77
78
|
|
|
78
79
|
Default is Standard (Qwen3 0.6B). Use Compact (GPT-2) when you need smaller files or browser deployment.
|
|
79
80
|
|
|
81
|
+
GPU acceleration is enabled by default (Metal on Mac, CUDA on Linux, falls back to CPU). Set `PAW_GPU_LAYERS=0` to force CPU if GPU causes issues.
|
|
82
|
+
|
|
80
83
|
## Browser SDK
|
|
81
84
|
|
|
82
85
|
Programs compiled with GPT-2 also run entirely in the browser via WebAssembly — no server needed, data never leaves the user's device.
|
|
@@ -99,9 +102,9 @@ See the [browser SDK repo](https://github.com/programasweights/programasweights-
|
|
|
99
102
|
|
|
100
103
|
PAW works with Cursor, Claude, Codex, and other AI coding assistants. Paste this into your agent's chat:
|
|
101
104
|
|
|
102
|
-
> I want to use ProgramAsWeights (PAW) to create fuzzy text functions that run locally. Read the instructions at https://programasweights.com/
|
|
105
|
+
> I want to use ProgramAsWeights (PAW) to create fuzzy text functions that run locally. Read the instructions at [https://programasweights.com/AGENTS.md](https://programasweights.com/AGENTS.md) and help me integrate it.
|
|
103
106
|
|
|
104
|
-
Or save [
|
|
107
|
+
Or save `[AGENTS.md](https://programasweights.com/agents)` to your project root — agents read it automatically.
|
|
105
108
|
|
|
106
109
|
## When to Use PAW
|
|
107
110
|
|
|
@@ -145,4 +148,4 @@ paw login
|
|
|
145
148
|
|
|
146
149
|
## License
|
|
147
150
|
|
|
148
|
-
MIT
|
|
151
|
+
MIT
|
|
@@ -18,7 +18,7 @@ import programasweights as paw
|
|
|
18
18
|
# Use a pre-compiled function (downloads once, runs locally forever)
|
|
19
19
|
fn = paw.function("email-triage")
|
|
20
20
|
fn("Urgent: the server is down!") # "immediate"
|
|
21
|
-
fn("Newsletter: spring picnic") # "
|
|
21
|
+
fn("Newsletter: spring picnic") # "wait"
|
|
22
22
|
|
|
23
23
|
# Compile your own from a description
|
|
24
24
|
program = paw.compile(
|
|
@@ -27,7 +27,7 @@ program = paw.compile(
|
|
|
27
27
|
slug="json-fixer" # optional: creates username/json-fixer handle
|
|
28
28
|
)
|
|
29
29
|
fn = paw.function(program.slug) # or paw.function(program.id)
|
|
30
|
-
fn("{name: 'Alice',}") # '{"name":
|
|
30
|
+
fn("{name: 'Alice',}") # '{"name":"Alice"}'
|
|
31
31
|
|
|
32
32
|
# Or compile and load in one step
|
|
33
33
|
fn = paw.compile_and_load("Classify sentiment as positive or negative")
|
|
@@ -36,17 +36,20 @@ fn("I love this!") # "positive"
|
|
|
36
36
|
|
|
37
37
|
## Two Compilers
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
39
|
+
|
|
40
|
+
| | Standard (Qwen3 0.6B) | Compact (GPT-2 124M) |
|
|
41
|
+
| --------------- | --------------------- | -------------------- |
|
|
42
|
+
| Compiler name | `paw-4b-qwen3-0.6b` | `paw-4b-gpt2` |
|
|
43
|
+
| Accuracy | Higher | Lower |
|
|
44
|
+
| Base model size | 594 MB | 105 MB |
|
|
45
|
+
| Program size | ~22 MB | ~5 MB |
|
|
46
|
+
| Local inference | ~0.05-0.5s per call | ~0.03-0.3s per call |
|
|
47
|
+
| Runs in browser | No | Yes (WebAssembly) |
|
|
47
48
|
|
|
48
49
|
Default is Standard (Qwen3 0.6B). Use Compact (GPT-2) when you need smaller files or browser deployment.
|
|
49
50
|
|
|
51
|
+
GPU acceleration is enabled by default (Metal on Mac, CUDA on Linux, falls back to CPU). Set `PAW_GPU_LAYERS=0` to force CPU if GPU causes issues.
|
|
52
|
+
|
|
50
53
|
## Browser SDK
|
|
51
54
|
|
|
52
55
|
Programs compiled with GPT-2 also run entirely in the browser via WebAssembly — no server needed, data never leaves the user's device.
|
|
@@ -69,9 +72,9 @@ See the [browser SDK repo](https://github.com/programasweights/programasweights-
|
|
|
69
72
|
|
|
70
73
|
PAW works with Cursor, Claude, Codex, and other AI coding assistants. Paste this into your agent's chat:
|
|
71
74
|
|
|
72
|
-
> I want to use ProgramAsWeights (PAW) to create fuzzy text functions that run locally. Read the instructions at https://programasweights.com/
|
|
75
|
+
> I want to use ProgramAsWeights (PAW) to create fuzzy text functions that run locally. Read the instructions at [https://programasweights.com/AGENTS.md](https://programasweights.com/AGENTS.md) and help me integrate it.
|
|
73
76
|
|
|
74
|
-
Or save [
|
|
77
|
+
Or save `[AGENTS.md](https://programasweights.com/agents)` to your project root — agents read it automatically.
|
|
75
78
|
|
|
76
79
|
## When to Use PAW
|
|
77
80
|
|
|
@@ -115,4 +118,4 @@ paw login
|
|
|
115
118
|
|
|
116
119
|
## License
|
|
117
120
|
|
|
118
|
-
MIT
|
|
121
|
+
MIT
|
|
@@ -20,7 +20,7 @@ result = fn("Thesis defense committee needs your signature by EOD")
|
|
|
20
20
|
print(result) # "immediate"
|
|
21
21
|
|
|
22
22
|
result = fn("Department newsletter: spring picnic next Friday")
|
|
23
|
-
print(result) # "
|
|
23
|
+
print(result) # "wait"
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## Compile Your Own
|
|
@@ -35,7 +35,7 @@ program = paw.compile(
|
|
|
35
35
|
|
|
36
36
|
# Use the compiled program
|
|
37
37
|
fn = paw.function(program.id)
|
|
38
|
-
fn("{name: 'Alice', age: 30,}") # '{"name":
|
|
38
|
+
fn("{name: 'Alice', age: 30,}") # '{"name":"Alice","age":30}'
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
## What Can You Build?
|
|
@@ -12,7 +12,7 @@ Quick start:
|
|
|
12
12
|
# Compile your own from a description
|
|
13
13
|
program = paw.compile("Fix malformed JSON: repair missing quotes and trailing commas")
|
|
14
14
|
fn = paw.function(program.id)
|
|
15
|
-
fn("{name: 'Alice',}") # '{"name":
|
|
15
|
+
fn("{name: 'Alice',}") # '{"name":"Alice"}'
|
|
16
16
|
|
|
17
17
|
API reference:
|
|
18
18
|
paw.compile(spec) Compile a spec on the server, returns Program
|
|
@@ -27,7 +27,7 @@ try:
|
|
|
27
27
|
from importlib.metadata import version as _meta_version
|
|
28
28
|
__version__ = _meta_version("programasweights")
|
|
29
29
|
except Exception:
|
|
30
|
-
__version__ = "0.
|
|
30
|
+
__version__ = "0.3.1"
|
|
31
31
|
|
|
32
32
|
from .config import get_api_url, get_api_key, set_api_key
|
|
33
33
|
|
|
@@ -65,7 +65,7 @@ def compile(
|
|
|
65
65
|
... )
|
|
66
66
|
>>> fn = paw.function(program.slug) # or paw.function(program.id)
|
|
67
67
|
>>> fn("{name: 'Alice',}")
|
|
68
|
-
'{"name":
|
|
68
|
+
'{"name":"Alice"}'
|
|
69
69
|
"""
|
|
70
70
|
from .client import PAWClient
|
|
71
71
|
from ._output import status
|
|
@@ -74,7 +74,13 @@ def compile(
|
|
|
74
74
|
result = client.compile(spec, compiler=compiler, name=name, tags=tags, public=public, slug=slug)
|
|
75
75
|
label = f"{result.id}"
|
|
76
76
|
if result.slug:
|
|
77
|
-
|
|
77
|
+
ver_str = f" v{result.version}" if result.version and result.version > 1 else ""
|
|
78
|
+
action_str = ""
|
|
79
|
+
if result.version_action == "no_change":
|
|
80
|
+
action_str = " (no changes)"
|
|
81
|
+
elif result.version_action == "promoted":
|
|
82
|
+
action_str = " set as main"
|
|
83
|
+
label = f"{result.slug}{ver_str}{action_str}"
|
|
78
84
|
status(f"Compiled: {label}")
|
|
79
85
|
return result
|
|
80
86
|
|
|
@@ -84,6 +90,7 @@ def function(
|
|
|
84
90
|
n_ctx: int = 2048,
|
|
85
91
|
n_gpu_layers: int | None = None,
|
|
86
92
|
verbose: bool = False,
|
|
93
|
+
offline: bool = False,
|
|
87
94
|
):
|
|
88
95
|
"""Load a compiled program for local inference via llama.cpp.
|
|
89
96
|
|
|
@@ -91,11 +98,15 @@ def function(
|
|
|
91
98
|
Subsequent calls use the local cache.
|
|
92
99
|
|
|
93
100
|
Args:
|
|
94
|
-
program_id: Program ID (str), slug
|
|
101
|
+
program_id: Program ID (str), slug (``da03/my-program``), pinned version
|
|
102
|
+
(``da03/my-program@v3``), or a ``Program`` object from compile().
|
|
95
103
|
n_ctx: Context window size for llama.cpp.
|
|
96
|
-
n_gpu_layers: GPU layers (-1 = all, 0 = CPU only). Defaults to
|
|
97
|
-
|
|
104
|
+
n_gpu_layers: GPU layers (-1 = all GPU, 0 = CPU only). Defaults to -1
|
|
105
|
+
(auto-uses Metal/CUDA if available, safe fallback to CPU).
|
|
106
|
+
Set ``PAW_GPU_LAYERS=0`` env var to force CPU-only.
|
|
98
107
|
verbose: Print llama.cpp debug output.
|
|
108
|
+
offline: Skip server check for slug resolution and use local cache only.
|
|
109
|
+
Also set via ``PAW_OFFLINE=1`` env var.
|
|
99
110
|
|
|
100
111
|
Returns:
|
|
101
112
|
A callable ``PawFunction`` that takes an input string and returns output.
|
|
@@ -105,8 +116,7 @@ def function(
|
|
|
105
116
|
>>> fn("Urgent: the server is down!")
|
|
106
117
|
'immediate'
|
|
107
118
|
|
|
108
|
-
>>>
|
|
109
|
-
>>> fn = paw.function(program) # accepts Program object directly
|
|
119
|
+
>>> fn = paw.function("da03/my-program@v2") # pinned version
|
|
110
120
|
"""
|
|
111
121
|
if hasattr(program_id, 'id'):
|
|
112
122
|
program_id = program_id.slug or program_id.id
|
|
@@ -116,21 +126,48 @@ def function(
|
|
|
116
126
|
from .runtime_llamacpp import PawFunction
|
|
117
127
|
|
|
118
128
|
if n_gpu_layers is None:
|
|
119
|
-
n_gpu_layers = int(os.environ.get("PAW_GPU_LAYERS", "
|
|
129
|
+
n_gpu_layers = int(os.environ.get("PAW_GPU_LAYERS", "-1"))
|
|
120
130
|
|
|
121
131
|
from ._output import status
|
|
122
132
|
|
|
123
133
|
resolved_id = program_id
|
|
124
134
|
if not re.fullmatch(r"[a-f0-9]{16,64}", program_id):
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
is_pinned = bool(re.search(r"@v\d+$", program_id))
|
|
136
|
+
use_offline = offline or os.environ.get("PAW_OFFLINE", "").strip() in ("1", "true", "yes")
|
|
137
|
+
|
|
138
|
+
if is_pinned:
|
|
139
|
+
cached = get_cached_slug(program_id)
|
|
140
|
+
if cached:
|
|
141
|
+
resolved_id = cached
|
|
142
|
+
else:
|
|
143
|
+
status(f"Resolving {program_id}...")
|
|
144
|
+
from .client import PAWClient
|
|
145
|
+
client = PAWClient(api_url=get_api_url(), api_key=get_api_key())
|
|
146
|
+
resolved_id = client.resolve_slug(program_id)
|
|
147
|
+
save_slug_mapping(program_id, resolved_id)
|
|
148
|
+
elif use_offline:
|
|
149
|
+
cached = get_cached_slug(program_id)
|
|
150
|
+
if cached:
|
|
151
|
+
resolved_id = cached
|
|
152
|
+
else:
|
|
153
|
+
raise RuntimeError(
|
|
154
|
+
f"No cached version of '{program_id}'. Cannot resolve offline. "
|
|
155
|
+
"Run once with internet to populate the cache."
|
|
156
|
+
)
|
|
128
157
|
else:
|
|
129
|
-
status(f"Resolving {program_id}...")
|
|
130
158
|
from .client import PAWClient
|
|
131
159
|
client = PAWClient(api_url=get_api_url(), api_key=get_api_key())
|
|
132
|
-
|
|
133
|
-
|
|
160
|
+
try:
|
|
161
|
+
status(f"Resolving {program_id}...")
|
|
162
|
+
resolved_id = client.resolve_slug(program_id)
|
|
163
|
+
save_slug_mapping(program_id, resolved_id)
|
|
164
|
+
except Exception:
|
|
165
|
+
cached = get_cached_slug(program_id)
|
|
166
|
+
if cached:
|
|
167
|
+
status(f"Warning: could not reach server, using cached version of {program_id}")
|
|
168
|
+
resolved_id = cached
|
|
169
|
+
else:
|
|
170
|
+
raise
|
|
134
171
|
|
|
135
172
|
if not is_program_cached(resolved_id):
|
|
136
173
|
from .client import PAWClient
|
|
@@ -221,6 +258,25 @@ def compile_and_load(
|
|
|
221
258
|
return function(program, n_ctx=n_ctx, n_gpu_layers=n_gpu_layers, verbose=verbose)
|
|
222
259
|
|
|
223
260
|
|
|
261
|
+
def list_versions(slug: str) -> dict:
|
|
262
|
+
"""List all versions of a named program (slug).
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
slug: Slug in ``username/slug-name`` or bare ``slug-name`` format.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Dict with ``slug``, ``main_version``, and ``versions`` list.
|
|
269
|
+
|
|
270
|
+
Example:
|
|
271
|
+
>>> versions = paw.list_versions("da03/bibtex-normalizer")
|
|
272
|
+
>>> for v in versions["versions"]:
|
|
273
|
+
... print(f"v{v['version']}: {v['program_id'][:12]} {'(main)' if v['is_main'] else ''}")
|
|
274
|
+
"""
|
|
275
|
+
from .client import PAWClient
|
|
276
|
+
client = PAWClient(api_url=get_api_url(), api_key=get_api_key())
|
|
277
|
+
return client.list_slug_versions(slug)
|
|
278
|
+
|
|
279
|
+
|
|
224
280
|
def list_programs(sort: str = "recent", per_page: int = 20, page: int = 1) -> dict:
|
|
225
281
|
"""List your compiled programs. Requires authentication (PAW_API_KEY).
|
|
226
282
|
|
|
@@ -242,6 +298,7 @@ __all__ = [
|
|
|
242
298
|
"compile_and_load",
|
|
243
299
|
"function",
|
|
244
300
|
"list_programs",
|
|
301
|
+
"list_versions",
|
|
245
302
|
"login",
|
|
246
303
|
"get_api_url",
|
|
247
304
|
"get_api_key",
|
|
@@ -27,6 +27,8 @@ class Program:
|
|
|
27
27
|
compiler_snapshot: Optional[str] = None
|
|
28
28
|
timings: Optional[dict] = None
|
|
29
29
|
error: Optional[str] = None
|
|
30
|
+
version: Optional[int] = None
|
|
31
|
+
version_action: Optional[str] = None
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
class PAWClient:
|
|
@@ -92,6 +94,8 @@ class PAWClient:
|
|
|
92
94
|
compiler_snapshot=data.get("compiler_snapshot"),
|
|
93
95
|
timings=data.get("timings"),
|
|
94
96
|
error=data.get("error"),
|
|
97
|
+
version=data.get("version"),
|
|
98
|
+
version_action=data.get("version_action"),
|
|
95
99
|
)
|
|
96
100
|
|
|
97
101
|
def resolve_slug(self, slug: str) -> str:
|
|
@@ -182,6 +186,16 @@ class PAWClient:
|
|
|
182
186
|
resp.raise_for_status()
|
|
183
187
|
return resp.json()
|
|
184
188
|
|
|
189
|
+
def list_slug_versions(self, slug: str) -> dict:
|
|
190
|
+
"""List all versions of a slug. Slug format: 'username/slug-name' or bare 'slug-name'."""
|
|
191
|
+
resp = httpx.get(
|
|
192
|
+
f"{self._api_url}/api/v1/programs/{slug}/versions",
|
|
193
|
+
headers=self._headers(),
|
|
194
|
+
timeout=10.0,
|
|
195
|
+
)
|
|
196
|
+
resp.raise_for_status()
|
|
197
|
+
return resp.json()
|
|
198
|
+
|
|
185
199
|
def list_programs(self, sort: str = "recent", per_page: int = 20, page: int = 1) -> dict:
|
|
186
200
|
"""List programs for the authenticated user."""
|
|
187
201
|
resp = httpx.get(
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "programasweights"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "Compile natural language specifications into neural programs that run locally via llama.cpp."
|
|
9
9
|
readme = "PYPI_README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{programasweights-0.2.8 → programasweights-0.3.1}/programasweights/runtime/interpreter_onnx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|