superlinear 0.1.0__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.
Files changed (62) hide show
  1. apps/__init__.py +4 -0
  2. apps/cli/__init__.py +8 -0
  3. apps/cli/bm25_rag.py +471 -0
  4. apps/cli/chat_repl.py +1497 -0
  5. apps/cli/client.py +195 -0
  6. apps/cli/docs_repl.py +2275 -0
  7. apps/cli/light_rag.py +729 -0
  8. apps/cli/local_snapshots.py +139 -0
  9. apps/cli/locks.py +214 -0
  10. apps/cli/main.py +457 -0
  11. apps/cli/output.py +32 -0
  12. apps/cli/server_cmds.py +516 -0
  13. apps/cli/session_cmds.py +491 -0
  14. apps/cli/snapshot_cmds.py +303 -0
  15. apps/cli/state.py +265 -0
  16. apps/server/__init__.py +4 -0
  17. apps/server/app.py +1363 -0
  18. apps/server/main.py +313 -0
  19. superlinear/__init__.py +114 -0
  20. superlinear/_version.py +3 -0
  21. superlinear/engine/__init__.py +10 -0
  22. superlinear/engine/adapters/__init__.py +12 -0
  23. superlinear/engine/adapters/base.py +91 -0
  24. superlinear/engine/adapters/superlinear.py +1233 -0
  25. superlinear/engine/chat_engine.py +1173 -0
  26. superlinear/engine/chat_types.py +130 -0
  27. superlinear/engine/registry.py +51 -0
  28. superlinear/engine/repetition.py +203 -0
  29. superlinear/engine/session_snapshots.py +451 -0
  30. superlinear/engine/tool_parser.py +83 -0
  31. superlinear/engine/types.py +42 -0
  32. superlinear/kernels/__init__.py +2 -0
  33. superlinear/kernels/common/__init__.py +21 -0
  34. superlinear/kernels/common/adjustment.py +106 -0
  35. superlinear/kernels/common/power.py +154 -0
  36. superlinear/kernels/superlinear/__init__.py +10 -0
  37. superlinear/kernels/superlinear/attention/__init__.py +78 -0
  38. superlinear/kernels/superlinear/attention/_prefill.py +940 -0
  39. superlinear/kernels/superlinear/attention/_sliding_window.py +1167 -0
  40. superlinear/kernels/superlinear/attention/api.py +433 -0
  41. superlinear/kernels/superlinear/search/__init__.py +33 -0
  42. superlinear/kernels/superlinear/search/_reference.py +204 -0
  43. superlinear/kernels/superlinear/search/_triton.py +488 -0
  44. superlinear/kernels/superlinear/search/_triton_gqa.py +534 -0
  45. superlinear/kernels/superlinear/search/api.py +200 -0
  46. superlinear/kernels/superlinear/span/__init__.py +41 -0
  47. superlinear/kernels/superlinear/span/_triton_bucketed_gqa.py +1461 -0
  48. superlinear/kernels/superlinear/span/_triton_forward.py +22 -0
  49. superlinear/kernels/superlinear/span/_triton_gqa.py +1226 -0
  50. superlinear/kernels/superlinear/span/_triton_impl.py +928 -0
  51. superlinear/kernels/superlinear/span/_triton_precomputed_sw.py +460 -0
  52. superlinear/kernels/superlinear/span/_triton_precomputed_sw_gqa.py +598 -0
  53. superlinear/kernels/superlinear/span/api.py +296 -0
  54. superlinear/kernels/superlinear/span/masks.py +187 -0
  55. superlinear/py.typed +0 -0
  56. superlinear/runtime.py +71 -0
  57. superlinear-0.1.0.dist-info/METADATA +469 -0
  58. superlinear-0.1.0.dist-info/RECORD +62 -0
  59. superlinear-0.1.0.dist-info/WHEEL +5 -0
  60. superlinear-0.1.0.dist-info/entry_points.txt +2 -0
  61. superlinear-0.1.0.dist-info/licenses/LICENSE +202 -0
  62. superlinear-0.1.0.dist-info/top_level.txt +2 -0
apps/cli/client.py ADDED
@@ -0,0 +1,195 @@
1
+ """HTTP client wrapper for communicating with the Superlinear HTTP server.
2
+
3
+ This module provides small, dependency-free primitives for JSON requests and SSE streaming.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import socket
10
+ import urllib.error
11
+ import urllib.parse
12
+ import urllib.request
13
+ from dataclasses import dataclass
14
+ from typing import Any, BinaryIO, Iterator
15
+
16
+
17
+ DEFAULT_URL = "http://127.0.0.1:8787"
18
+
19
+
20
+ @dataclass(frozen=True)
21
+ class HttpError(RuntimeError):
22
+ message: str
23
+ url: str | None = None
24
+ status_code: int | None = None
25
+ body: str | None = None
26
+
27
+ def __str__(self) -> str: # pragma: no cover
28
+ parts = [self.message]
29
+ if self.status_code is not None:
30
+ parts.append(f"status={self.status_code}")
31
+ if self.url:
32
+ parts.append(f"url={self.url}")
33
+ if self.body:
34
+ parts.append(f"body={self.body}")
35
+ return " ".join(parts)
36
+
37
+
38
+ def _join_url(base_url: str, path: str) -> str:
39
+ if not path.startswith("/"):
40
+ path = "/" + path
41
+ # Ensure base_url ends with "/" so urljoin doesn't drop the path.
42
+ return urllib.parse.urljoin(base_url.rstrip("/") + "/", path.lstrip("/"))
43
+
44
+
45
+ def iter_sse_data(stream: BinaryIO) -> Iterator[str]:
46
+ """Yield decoded SSE `data:` payloads, one per event (without the trailing blank line)."""
47
+ data_lines: list[str] = []
48
+ for raw in stream:
49
+ try:
50
+ line = raw.decode("utf-8", errors="replace")
51
+ except Exception:
52
+ continue
53
+ line = line.rstrip("\r\n")
54
+ if not line:
55
+ if data_lines:
56
+ yield "\n".join(data_lines)
57
+ data_lines = []
58
+ continue
59
+ if line.startswith("data:"):
60
+ data_lines.append(line[5:].lstrip())
61
+ continue
62
+
63
+ if data_lines:
64
+ yield "\n".join(data_lines)
65
+
66
+
67
+ def iter_sse_json(stream: BinaryIO) -> Iterator[dict[str, Any]]:
68
+ """Yield JSON-decoded SSE `data:` payloads; stops on `[DONE]`."""
69
+ for payload in iter_sse_data(stream):
70
+ if payload == "[DONE]":
71
+ return
72
+ yield json.loads(payload)
73
+
74
+
75
+ class SuperlinearClient:
76
+ def __init__(self, *, base_url: str = DEFAULT_URL, timeout_s: float = 300.0):
77
+ self.base_url = base_url.rstrip("/")
78
+ self.timeout_s = float(timeout_s)
79
+
80
+ def request_json(
81
+ self,
82
+ method: str,
83
+ path: str,
84
+ *,
85
+ payload: Any | None = None,
86
+ timeout_s: float | None = None,
87
+ headers: dict[str, str] | None = None,
88
+ ) -> Any:
89
+ url = _join_url(self.base_url, path)
90
+
91
+ body: bytes | None = None
92
+ if payload is not None:
93
+ body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
94
+
95
+ req = urllib.request.Request(url=url, method=method.upper(), data=body)
96
+ req.add_header("Accept", "application/json")
97
+ if payload is not None:
98
+ req.add_header("Content-Type", "application/json")
99
+ if headers:
100
+ for k, v in headers.items():
101
+ req.add_header(k, v)
102
+
103
+ try:
104
+ with urllib.request.urlopen(req, timeout=self.timeout_s if timeout_s is None else timeout_s) as resp:
105
+ raw = resp.read()
106
+ try:
107
+ return json.loads(raw.decode("utf-8"))
108
+ except Exception as exc:
109
+ raise HttpError(
110
+ "Invalid JSON response",
111
+ url=url,
112
+ status_code=getattr(resp, "status", None),
113
+ body=raw.decode("utf-8", errors="replace"),
114
+ ) from exc
115
+ except urllib.error.HTTPError as exc:
116
+ body_text: str | None
117
+ try:
118
+ body_text = exc.read().decode("utf-8", errors="replace")
119
+ except Exception:
120
+ body_text = None
121
+ raise HttpError(
122
+ "HTTP error",
123
+ url=url,
124
+ status_code=getattr(exc, "code", None),
125
+ body=body_text,
126
+ ) from exc
127
+ except urllib.error.URLError as exc:
128
+ raise HttpError("Failed to reach server", url=url) from exc
129
+ except socket.timeout as exc:
130
+ raise HttpError("Request timed out", url=url) from exc
131
+
132
+ def request_sse(
133
+ self,
134
+ method: str,
135
+ path: str,
136
+ *,
137
+ payload: Any | None = None,
138
+ timeout_s: float | None = None,
139
+ headers: dict[str, str] | None = None,
140
+ ) -> Iterator[dict[str, Any]]:
141
+ url = _join_url(self.base_url, path)
142
+ body: bytes | None = None
143
+ if payload is not None:
144
+ body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
145
+
146
+ req = urllib.request.Request(url=url, method=method.upper(), data=body)
147
+ req.add_header("Accept", "text/event-stream")
148
+ if payload is not None:
149
+ req.add_header("Content-Type", "application/json")
150
+ if headers:
151
+ for k, v in headers.items():
152
+ req.add_header(k, v)
153
+
154
+ try:
155
+ resp = urllib.request.urlopen(req, timeout=self.timeout_s if timeout_s is None else timeout_s)
156
+ except urllib.error.HTTPError as exc:
157
+ body_text: str | None
158
+ try:
159
+ body_text = exc.read().decode("utf-8", errors="replace")
160
+ except Exception:
161
+ body_text = None
162
+ raise HttpError(
163
+ "HTTP error",
164
+ url=url,
165
+ status_code=getattr(exc, "code", None),
166
+ body=body_text,
167
+ ) from exc
168
+ except urllib.error.URLError as exc:
169
+ raise HttpError("Failed to reach server", url=url) from exc
170
+ except socket.timeout as exc:
171
+ raise HttpError("Request timed out", url=url) from exc
172
+
173
+ try:
174
+ yield from iter_sse_json(resp)
175
+ finally:
176
+ try:
177
+ resp.close()
178
+ except Exception:
179
+ pass
180
+
181
+ def health(self) -> dict[str, Any]:
182
+ result = self.request_json("GET", "/health", timeout_s=min(self.timeout_s, 5.0))
183
+ if not isinstance(result, dict):
184
+ raise HttpError("Invalid /health response", url=_join_url(self.base_url, "/health"))
185
+ return result
186
+
187
+ def list_models(self) -> list[dict[str, Any]]:
188
+ result = self.request_json("GET", "/v1/models")
189
+ if not isinstance(result, dict) or not isinstance(result.get("data"), list):
190
+ raise HttpError("Invalid /v1/models response", url=_join_url(self.base_url, "/v1/models"))
191
+ out: list[dict[str, Any]] = []
192
+ for item in result["data"]:
193
+ if isinstance(item, dict):
194
+ out.append(item)
195
+ return out