programasweights 0.2.0__py3-none-any.whl → 0.2.2.dev1__py3-none-any.whl
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/__init__.py +59 -3
- programasweights/cli.py +3 -1
- programasweights/client.py +25 -7
- programasweights/runtime_llamacpp.py +19 -6
- {programasweights-0.2.0.dist-info → programasweights-0.2.2.dev1.dist-info}/METADATA +1 -1
- {programasweights-0.2.0.dist-info → programasweights-0.2.2.dev1.dist-info}/RECORD +9 -9
- {programasweights-0.2.0.dist-info → programasweights-0.2.2.dev1.dist-info}/WHEEL +0 -0
- {programasweights-0.2.0.dist-info → programasweights-0.2.2.dev1.dist-info}/entry_points.txt +0 -0
- {programasweights-0.2.0.dist-info → programasweights-0.2.2.dev1.dist-info}/licenses/LICENSE +0 -0
programasweights/__init__.py
CHANGED
|
@@ -22,7 +22,7 @@ API reference:
|
|
|
22
22
|
paw.api_key API key (set via login() or PAW_API_KEY env var)
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
-
__version__ = "0.2.
|
|
25
|
+
__version__ = "0.2.2.dev1"
|
|
26
26
|
|
|
27
27
|
from .config import get_api_url, get_api_key, set_api_key
|
|
28
28
|
|
|
@@ -72,7 +72,7 @@ def compile(
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def function(
|
|
75
|
-
program_id
|
|
75
|
+
program_id,
|
|
76
76
|
n_ctx: int = 2048,
|
|
77
77
|
n_gpu_layers: int | None = None,
|
|
78
78
|
verbose: bool = False,
|
|
@@ -83,7 +83,7 @@ def function(
|
|
|
83
83
|
Subsequent calls use the local cache.
|
|
84
84
|
|
|
85
85
|
Args:
|
|
86
|
-
program_id:
|
|
86
|
+
program_id: Program ID (str), slug, or a ``Program`` object from compile().
|
|
87
87
|
n_ctx: Context window size for llama.cpp.
|
|
88
88
|
n_gpu_layers: GPU layers (-1 = all, 0 = CPU only). Defaults to CPU.
|
|
89
89
|
Set ``PAW_GPU_LAYERS`` env var or pass explicitly for GPU acceleration.
|
|
@@ -96,7 +96,12 @@ def function(
|
|
|
96
96
|
>>> fn = paw.function("email-triage")
|
|
97
97
|
>>> fn("Urgent: the server is down!")
|
|
98
98
|
'immediate'
|
|
99
|
+
|
|
100
|
+
>>> program = paw.compile("Classify sentiment")
|
|
101
|
+
>>> fn = paw.function(program) # accepts Program object directly
|
|
99
102
|
"""
|
|
103
|
+
if hasattr(program_id, 'id'):
|
|
104
|
+
program_id = program_id.slug or program_id.id
|
|
100
105
|
import os
|
|
101
106
|
import re
|
|
102
107
|
from .cache import is_program_cached, get_program_dir, get_cached_slug, save_slug_mapping
|
|
@@ -175,9 +180,60 @@ def login(key: str | None = None):
|
|
|
175
180
|
print("You can also set the PAW_API_KEY environment variable.")
|
|
176
181
|
|
|
177
182
|
|
|
183
|
+
def compile_and_load(
|
|
184
|
+
spec: str,
|
|
185
|
+
compiler: str = "paw-4b-qwen3-0.6b",
|
|
186
|
+
n_ctx: int = 2048,
|
|
187
|
+
n_gpu_layers: int | None = None,
|
|
188
|
+
verbose: bool = False,
|
|
189
|
+
**compile_kwargs,
|
|
190
|
+
):
|
|
191
|
+
"""Compile a spec and immediately load it for local inference.
|
|
192
|
+
|
|
193
|
+
Convenience wrapper that combines ``paw.compile()`` and ``paw.function()``
|
|
194
|
+
into a single call.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
spec: Natural language specification.
|
|
198
|
+
compiler: Compiler model name.
|
|
199
|
+
n_ctx: Context window size for llama.cpp.
|
|
200
|
+
n_gpu_layers: GPU layers (-1 = all, 0 = CPU only).
|
|
201
|
+
verbose: Print llama.cpp debug output.
|
|
202
|
+
**compile_kwargs: Additional args passed to compile (slug, public, etc.)
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
A callable ``PawFunction``.
|
|
206
|
+
|
|
207
|
+
Example:
|
|
208
|
+
>>> fn = paw.compile_and_load("Classify sentiment as positive or negative")
|
|
209
|
+
>>> fn("I love this!")
|
|
210
|
+
'positive'
|
|
211
|
+
"""
|
|
212
|
+
program = compile(spec, compiler=compiler, **compile_kwargs)
|
|
213
|
+
return function(program, n_ctx=n_ctx, n_gpu_layers=n_gpu_layers, verbose=verbose)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def list_programs(sort: str = "recent", per_page: int = 20, page: int = 1) -> dict:
|
|
217
|
+
"""List your compiled programs. Requires authentication (PAW_API_KEY).
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
Dict with ``programs`` (list), ``total``, ``page``, ``per_page``.
|
|
221
|
+
|
|
222
|
+
Example:
|
|
223
|
+
>>> programs = paw.list_programs()
|
|
224
|
+
>>> for p in programs["programs"]:
|
|
225
|
+
... print(p["id"], p["name"])
|
|
226
|
+
"""
|
|
227
|
+
from .client import PAWClient
|
|
228
|
+
client = PAWClient(api_url=api_url, api_key=api_key)
|
|
229
|
+
return client.list_programs(sort=sort, per_page=per_page, page=page)
|
|
230
|
+
|
|
231
|
+
|
|
178
232
|
__all__ = [
|
|
179
233
|
"compile",
|
|
234
|
+
"compile_and_load",
|
|
180
235
|
"function",
|
|
236
|
+
"list_programs",
|
|
181
237
|
"login",
|
|
182
238
|
"api_url",
|
|
183
239
|
"api_key",
|
programasweights/cli.py
CHANGED
|
@@ -27,7 +27,8 @@ def cmd_compile(args):
|
|
|
27
27
|
if not args.json:
|
|
28
28
|
print(f"Compiling: {args.spec[:80]}...")
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
public = not getattr(args, 'private', False)
|
|
31
|
+
program = paw.compile(args.spec, compiler=args.compiler, slug=getattr(args, 'slug', None), public=public)
|
|
31
32
|
|
|
32
33
|
if args.json:
|
|
33
34
|
print(json.dumps({
|
|
@@ -170,6 +171,7 @@ def main():
|
|
|
170
171
|
p.add_argument("--spec", required=True, help="Natural language specification")
|
|
171
172
|
p.add_argument("--compiler", default="paw-4b-qwen3-0.6b", help="Compiler model")
|
|
172
173
|
p.add_argument("--slug", default=None, help="URL-safe handle (e.g. 'message-classifier')")
|
|
174
|
+
p.add_argument("--private", action="store_true", help="Make program private (not listed on hub)")
|
|
173
175
|
p.add_argument("--json", action="store_true", help="JSON output")
|
|
174
176
|
|
|
175
177
|
p = sub.add_parser("run", help="Run a program locally via llama.cpp")
|
programasweights/client.py
CHANGED
|
@@ -108,18 +108,25 @@ class PAWClient:
|
|
|
108
108
|
"""Download a .paw bundle to the local cache.
|
|
109
109
|
|
|
110
110
|
Returns the path to the extracted program directory.
|
|
111
|
+
Retries on 404 since freshly compiled programs may still be uploading.
|
|
111
112
|
"""
|
|
112
113
|
program_dir = config.get_programs_dir() / program_id
|
|
113
114
|
if (program_dir / "prompt_template.txt").exists():
|
|
114
115
|
return program_dir
|
|
115
116
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
max_retries = 10
|
|
118
|
+
for attempt in range(max_retries):
|
|
119
|
+
resp = httpx.get(
|
|
120
|
+
f"{self._api_url}/api/v1/programs/{program_id}/download",
|
|
121
|
+
headers=self._headers(),
|
|
122
|
+
timeout=60.0,
|
|
123
|
+
follow_redirects=True,
|
|
124
|
+
)
|
|
125
|
+
if resp.status_code == 404 and attempt < max_retries - 1:
|
|
126
|
+
time.sleep(3)
|
|
127
|
+
continue
|
|
128
|
+
resp.raise_for_status()
|
|
129
|
+
break
|
|
123
130
|
|
|
124
131
|
program_dir.mkdir(parents=True, exist_ok=True)
|
|
125
132
|
paw_path = program_dir / f"{program_id}.paw"
|
|
@@ -140,6 +147,17 @@ class PAWClient:
|
|
|
140
147
|
resp.raise_for_status()
|
|
141
148
|
return resp.json()
|
|
142
149
|
|
|
150
|
+
def list_programs(self, sort: str = "recent", per_page: int = 20, page: int = 1) -> dict:
|
|
151
|
+
"""List programs for the authenticated user."""
|
|
152
|
+
resp = httpx.get(
|
|
153
|
+
f"{self._api_url}/api/v1/programs",
|
|
154
|
+
params={"mine": "true", "sort": sort, "per_page": per_page, "page": page},
|
|
155
|
+
headers=self._headers(),
|
|
156
|
+
timeout=10.0,
|
|
157
|
+
)
|
|
158
|
+
resp.raise_for_status()
|
|
159
|
+
return resp.json()
|
|
160
|
+
|
|
143
161
|
|
|
144
162
|
_default_client: PAWClient | None = None
|
|
145
163
|
|
|
@@ -53,12 +53,25 @@ class PawFunction:
|
|
|
53
53
|
interpreter = self._meta.get("interpreter", "Qwen/Qwen3-0.6B")
|
|
54
54
|
base_model_path = cache.get_base_model_path(interpreter)
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
if not verbose:
|
|
57
|
+
import os as _os, sys as _sys
|
|
58
|
+
_stderr_fd = _sys.stderr.fileno()
|
|
59
|
+
_devnull = _os.open(_os.devnull, _os.O_WRONLY)
|
|
60
|
+
_old_stderr = _os.dup(_stderr_fd)
|
|
61
|
+
_os.dup2(_devnull, _stderr_fd)
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
self._llm = Llama(
|
|
65
|
+
model_path=str(base_model_path),
|
|
66
|
+
n_ctx=n_ctx,
|
|
67
|
+
n_gpu_layers=n_gpu_layers,
|
|
68
|
+
verbose=verbose,
|
|
69
|
+
)
|
|
70
|
+
finally:
|
|
71
|
+
if not verbose:
|
|
72
|
+
_os.dup2(_old_stderr, _stderr_fd)
|
|
73
|
+
_os.close(_devnull)
|
|
74
|
+
_os.close(_old_stderr)
|
|
62
75
|
|
|
63
76
|
adapter_path = program_dir / "adapter.gguf"
|
|
64
77
|
if adapter_path.exists():
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: programasweights
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2.dev1
|
|
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
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
programasweights/__init__.py,sha256=
|
|
1
|
+
programasweights/__init__.py,sha256=8SpAl6BpIBGHy1WsWZQ4EHGnHevzqsjVnMzKoaAjMpo,7852
|
|
2
2
|
programasweights/artifacts.py,sha256=bSRZgYadAYyuH9aIW6P3VocExfGDGAHeDuj8vod5-Bo,1968
|
|
3
3
|
programasweights/cache.py,sha256=7L4D5juQLtARVT4aEqzy9N2Lz6xUv9uk7LBZMuJJFrY,3866
|
|
4
|
-
programasweights/cli.py,sha256=
|
|
5
|
-
programasweights/client.py,sha256=
|
|
4
|
+
programasweights/cli.py,sha256=X0M3OddGvsBJXjcaKw0qebaU9koe8r30BHgj9Wbf5WM,6840
|
|
5
|
+
programasweights/client.py,sha256=DlgEEgluTZqQJnfYeVh5bW74ZcyxHmrE_3fFgufHsgQ,5153
|
|
6
6
|
programasweights/config.py,sha256=zQFnVNfYR4bFx2DsZheMnPy2yd9T4-fe0u2sG1GluE8,1553
|
|
7
7
|
programasweights/convert_peft_to_paw.py,sha256=yvavaAzLUqc-lFHEC_9AOhsuI-fCobu6k-GDMVQdOHk,6521
|
|
8
8
|
programasweights/paw_format.py,sha256=wRXolwtnPgKoopiJC8-yMVZZtiwB-PoAqaWpDFKMoj8,10679
|
|
9
|
-
programasweights/runtime_llamacpp.py,sha256=
|
|
9
|
+
programasweights/runtime_llamacpp.py,sha256=7uuJx6sD1TVu1pj_qikT8CK4_I7aoYvy3UHOc-5gXOM,6929
|
|
10
10
|
programasweights/compiler/__init__.py,sha256=_q0L02k6Cl9zyvxKQlMuW2o6w7cX6OZ_bZ9wHuZqs18,9508
|
|
11
11
|
programasweights/compiler/dummy.py,sha256=PcLwijRNM4q2E9PNUcfCPf_y08QjsteVENR0TVsOIfY,1011
|
|
12
12
|
programasweights/runtime/__init__.py,sha256=S4jp7-eWAcMa0X417U7P6HkTL1j3v8ffQA-nneh9wY0,549
|
|
13
13
|
programasweights/runtime/interpreter.py,sha256=brYCtatSsu23lq87cuki4MViqZX6U32LBw7Z3USbQmA,19632
|
|
14
14
|
programasweights/runtime/interpreter_onnx.py,sha256=kzYKmwg_h0tVhoQlixJGKoHPVhcCK22AcHG59oeYX2Q,21559
|
|
15
|
-
programasweights-0.2.
|
|
16
|
-
programasweights-0.2.
|
|
17
|
-
programasweights-0.2.
|
|
18
|
-
programasweights-0.2.
|
|
19
|
-
programasweights-0.2.
|
|
15
|
+
programasweights-0.2.2.dev1.dist-info/METADATA,sha256=9EPrwbhEKMuLSLxN1NV_nZpcjiZhDrrLVecdqJFx5zg,5778
|
|
16
|
+
programasweights-0.2.2.dev1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
17
|
+
programasweights-0.2.2.dev1.dist-info/entry_points.txt,sha256=l4ZnfCPU0oMzhGB9T2Fv9AnDbSCMM70KUUJVtSvMJBc,50
|
|
18
|
+
programasweights-0.2.2.dev1.dist-info/licenses/LICENSE,sha256=6GRcDlVhbPMVgkKqBt0cgwyvtvFxpdp4s2vcYKST4r0,1073
|
|
19
|
+
programasweights-0.2.2.dev1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|