hugpy-resources 0.1.3__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 (131) hide show
  1. hugpy_resources/__init__.py +3 -0
  2. hugpy_resources/imports/__init__.py +35 -0
  3. hugpy_resources/imports/classes/__init__.py +24 -0
  4. hugpy_resources/imports/classes/database.py +49 -0
  5. hugpy_resources/imports/classes/errors.py +74 -0
  6. hugpy_resources/imports/classes/http.py +116 -0
  7. hugpy_resources/imports/classes/nvml.py +32 -0
  8. hugpy_resources/imports/classes/thinking.py +77 -0
  9. hugpy_resources/imports/classes/tool_calls.py +53 -0
  10. hugpy_resources/imports/constants/__init__.py +45 -0
  11. hugpy_resources/imports/constants/admission.py +19 -0
  12. hugpy_resources/imports/constants/architecture.py +84 -0
  13. hugpy_resources/imports/constants/audit.py +6 -0
  14. hugpy_resources/imports/constants/comfy.py +15 -0
  15. hugpy_resources/imports/constants/context.py +37 -0
  16. hugpy_resources/imports/constants/contracts.py +279 -0
  17. hugpy_resources/imports/constants/cpu.py +19 -0
  18. hugpy_resources/imports/constants/drives.py +26 -0
  19. hugpy_resources/imports/constants/engines.py +15 -0
  20. hugpy_resources/imports/constants/formats.py +114 -0
  21. hugpy_resources/imports/constants/gguf.py +88 -0
  22. hugpy_resources/imports/constants/hardware.py +21 -0
  23. hugpy_resources/imports/constants/identity.py +16 -0
  24. hugpy_resources/imports/constants/math.py +38 -0
  25. hugpy_resources/imports/constants/memory.py +31 -0
  26. hugpy_resources/imports/constants/placement.py +140 -0
  27. hugpy_resources/imports/constants/platform.py +29 -0
  28. hugpy_resources/imports/constants/runtime.py +175 -0
  29. hugpy_resources/imports/constants/tensors.py +53 -0
  30. hugpy_resources/imports/constants/terms.py +221 -0
  31. hugpy_resources/imports/constants/text.py +84 -0
  32. hugpy_resources/imports/constants/timing.py +39 -0
  33. hugpy_resources/imports/constants/tool_calls.py +22 -0
  34. hugpy_resources/imports/constants/transfer.py +28 -0
  35. hugpy_resources/imports/constants/validation.py +52 -0
  36. hugpy_resources/imports/functions/__init__.py +157 -0
  37. hugpy_resources/imports/functions/application_paths.py +185 -0
  38. hugpy_resources/imports/functions/argument_parsing.py +27 -0
  39. hugpy_resources/imports/functions/ast_utils.py +26 -0
  40. hugpy_resources/imports/functions/atomic_files.py +25 -0
  41. hugpy_resources/imports/functions/binary_data.py +39 -0
  42. hugpy_resources/imports/functions/block_io.py +78 -0
  43. hugpy_resources/imports/functions/cache.py +92 -0
  44. hugpy_resources/imports/functions/callables.py +10 -0
  45. hugpy_resources/imports/functions/coercion.py +22 -0
  46. hugpy_resources/imports/functions/comfy_metadata.py +101 -0
  47. hugpy_resources/imports/functions/configuration.py +29 -0
  48. hugpy_resources/imports/functions/content_proofs.py +57 -0
  49. hugpy_resources/imports/functions/cpu_activity.py +31 -0
  50. hugpy_resources/imports/functions/devices.py +10 -0
  51. hugpy_resources/imports/functions/engine_metadata.py +43 -0
  52. hugpy_resources/imports/functions/engine_probes.py +217 -0
  53. hugpy_resources/imports/functions/env_files.py +19 -0
  54. hugpy_resources/imports/functions/env_values.py +70 -0
  55. hugpy_resources/imports/functions/environment.py +82 -0
  56. hugpy_resources/imports/functions/evidence.py +37 -0
  57. hugpy_resources/imports/functions/executables.py +51 -0
  58. hugpy_resources/imports/functions/feasibility.py +130 -0
  59. hugpy_resources/imports/functions/file_transfer.py +94 -0
  60. hugpy_resources/imports/functions/file_types.py +256 -0
  61. hugpy_resources/imports/functions/filesystem.py +275 -0
  62. hugpy_resources/imports/functions/filesystems.py +30 -0
  63. hugpy_resources/imports/functions/formatting.py +55 -0
  64. hugpy_resources/imports/functions/geometry.py +217 -0
  65. hugpy_resources/imports/functions/gguf_cache.py +64 -0
  66. hugpy_resources/imports/functions/gguf_headers.py +323 -0
  67. hugpy_resources/imports/functions/gguf_moe.py +356 -0
  68. hugpy_resources/imports/functions/gguf_structure.py +288 -0
  69. hugpy_resources/imports/functions/gguf_variants.py +124 -0
  70. hugpy_resources/imports/functions/hardware_inventory.py +238 -0
  71. hugpy_resources/imports/functions/hashing.py +38 -0
  72. hugpy_resources/imports/functions/host_memory.py +121 -0
  73. hugpy_resources/imports/functions/http_auth.py +36 -0
  74. hugpy_resources/imports/functions/inference_children.py +108 -0
  75. hugpy_resources/imports/functions/inference_timings.py +182 -0
  76. hugpy_resources/imports/functions/integers.py +14 -0
  77. hugpy_resources/imports/functions/json_http.py +22 -0
  78. hugpy_resources/imports/functions/json_rows.py +75 -0
  79. hugpy_resources/imports/functions/json_utils.py +52 -0
  80. hugpy_resources/imports/functions/kv_cache.py +45 -0
  81. hugpy_resources/imports/functions/kv_cells.py +22 -0
  82. hugpy_resources/imports/functions/locking.py +21 -0
  83. hugpy_resources/imports/functions/memory.py +23 -0
  84. hugpy_resources/imports/functions/messages.py +38 -0
  85. hugpy_resources/imports/functions/model_config.py +58 -0
  86. hugpy_resources/imports/functions/model_files.py +94 -0
  87. hugpy_resources/imports/functions/nvml.py +192 -0
  88. hugpy_resources/imports/functions/openai_protocol.py +41 -0
  89. hugpy_resources/imports/functions/paths.py +245 -0
  90. hugpy_resources/imports/functions/placement.py +32 -0
  91. hugpy_resources/imports/functions/ports.py +21 -0
  92. hugpy_resources/imports/functions/processes.py +132 -0
  93. hugpy_resources/imports/functions/profile_metadata.py +30 -0
  94. hugpy_resources/imports/functions/python_environments.py +26 -0
  95. hugpy_resources/imports/functions/quantization.py +50 -0
  96. hugpy_resources/imports/functions/recurrent_state.py +33 -0
  97. hugpy_resources/imports/functions/requirements.py +204 -0
  98. hugpy_resources/imports/functions/row_history.py +77 -0
  99. hugpy_resources/imports/functions/row_values.py +29 -0
  100. hugpy_resources/imports/functions/runtime.py +236 -0
  101. hugpy_resources/imports/functions/safetensors.py +127 -0
  102. hugpy_resources/imports/functions/search.py +884 -0
  103. hugpy_resources/imports/functions/selected_artifacts.py +345 -0
  104. hugpy_resources/imports/functions/source_fingerprints.py +26 -0
  105. hugpy_resources/imports/functions/sql_quoting.py +11 -0
  106. hugpy_resources/imports/functions/sqlite.py +26 -0
  107. hugpy_resources/imports/functions/sqlite_callbacks.py +75 -0
  108. hugpy_resources/imports/functions/sqlite_connections.py +89 -0
  109. hugpy_resources/imports/functions/state.py +41 -0
  110. hugpy_resources/imports/functions/statistics.py +18 -0
  111. hugpy_resources/imports/functions/structured_data.py +72 -0
  112. hugpy_resources/imports/functions/tensor_files.py +193 -0
  113. hugpy_resources/imports/functions/tensors.py +25 -0
  114. hugpy_resources/imports/functions/terminal_text.py +82 -0
  115. hugpy_resources/imports/functions/text.py +104 -0
  116. hugpy_resources/imports/functions/thinking.py +45 -0
  117. hugpy_resources/imports/functions/time_utils.py +37 -0
  118. hugpy_resources/imports/functions/timing.py +415 -0
  119. hugpy_resources/imports/functions/tool_calls.py +86 -0
  120. hugpy_resources/imports/functions/tool_deltas.py +25 -0
  121. hugpy_resources/imports/functions/transformer_facts.py +336 -0
  122. hugpy_resources/imports/functions/units.py +25 -0
  123. hugpy_resources/imports/functions/urls.py +23 -0
  124. hugpy_resources/imports/init_imports.py +80 -0
  125. hugpy_resources/imports/mime_types.json +263 -0
  126. hugpy_resources/imports/terms.json +3841 -0
  127. hugpy_resources/lazy_imports.py +53 -0
  128. hugpy_resources-0.1.3.dist-info/METADATA +10 -0
  129. hugpy_resources-0.1.3.dist-info/RECORD +131 -0
  130. hugpy_resources-0.1.3.dist-info/WHEEL +5 -0
  131. hugpy_resources-0.1.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,3 @@
1
+ """Pure resource contracts; no engines, database connections or hardware probes."""
2
+
3
+
@@ -0,0 +1,35 @@
1
+ """Public shared constants, classes and generic utilities.
2
+
3
+ Function/class ownership is declared only in their projections. Constants load
4
+ on first use; optional function implementations load only when requested.
5
+ """
6
+
7
+ from importlib import import_module as _import_module
8
+
9
+ from . import classes as _classes
10
+ from . import functions as _functions
11
+
12
+
13
+ def __getattr__(name):
14
+ if name == "__all__":
15
+ constants = _import_module(f"{__name__}.constants")
16
+ value = list(dict.fromkeys([
17
+ *constants.__all__, *_functions.__all__, *_classes.__all__,
18
+ ]))
19
+ elif name in _functions.__all__:
20
+ # A loaded child module can have the same name as an exported function
21
+ # (for example environment). Resolve the declared owner explicitly.
22
+ value = _functions.__getattr__(name)
23
+ elif name in _classes.__all__:
24
+ value = _classes.__getattr__(name)
25
+ else:
26
+ constants = _import_module(f"{__name__}.constants")
27
+ if name not in constants.__all__:
28
+ raise AttributeError(f"{__name__!r} has no attribute {name!r}") from None
29
+ value = getattr(constants, name)
30
+ globals()[name] = value
31
+ return value
32
+
33
+
34
+ def __dir__():
35
+ return sorted(set(globals()) | set(__getattr__("__all__")))
@@ -0,0 +1,24 @@
1
+ """Canonical reusable errors, records, protocol parsers and HTTP scaffold."""
2
+
3
+ from hugpy_resources.lazy_imports import import_registry, resolve_import
4
+
5
+ from ..init_imports import import_module
6
+
7
+ _EXPORTS = import_registry({
8
+ '.errors': (
9
+ 'GGUFHeaderError PathEscape LocalRequestError ChatRequestError TaskRequestError '
10
+ 'StoreError'
11
+ ),
12
+ '.database': 'Row Cursor',
13
+ '.nvml': '_MemV2 _Mem _ProcV3',
14
+ '.thinking': 'ThinkSplitter',
15
+ '.tool_calls': 'StreamSplitter',
16
+ '.http': 'make_child_handler',
17
+ })
18
+
19
+
20
+ def __getattr__(name):
21
+ return resolve_import(globals(), _EXPORTS, name)
22
+
23
+
24
+ __all__ = list(_EXPORTS)
@@ -0,0 +1,49 @@
1
+ """Reusable database definitions."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ class Row:
7
+ """sqlite3.Row compatible access, including duplicate projection names."""
8
+
9
+ def __init__(self, names, values):
10
+ self._names, self._values = tuple(names), tuple(values)
11
+
12
+ def __getitem__(self, key):
13
+ if isinstance(key, (int, slice)):
14
+ return self._values[key]
15
+ try:
16
+ return self._values[self._names.index(key)]
17
+ except ValueError:
18
+ raise KeyError(key) from None
19
+
20
+ def __iter__(self):
21
+ return iter(self._values)
22
+
23
+ def __len__(self):
24
+ return len(self._values)
25
+
26
+ def keys(self):
27
+ return self._names
28
+
29
+ def get(self, key, default=None):
30
+ try:
31
+ return self[key]
32
+ except KeyError:
33
+ return default
34
+
35
+
36
+ class Cursor:
37
+ def __init__(self, rows, rowcount=0, lastrowid=None, columns=(), values=()):
38
+ self.rows = iter(
39
+ [Row(columns, row) for row in values]
40
+ if columns
41
+ else [Row(row.keys(), row.values()) for row in rows]
42
+ )
43
+ self.rowcount, self.lastrowid = rowcount, lastrowid
44
+
45
+ def fetchone(self):
46
+ return next(self.rows, None)
47
+
48
+ def fetchall(self):
49
+ return list(self.rows)
@@ -0,0 +1,74 @@
1
+ """Reusable parsing errors."""
2
+
3
+
4
+ class GGUFHeaderError(ValueError):
5
+ """The GGUF header is unreadable (magic, version, extent or EOF)."""
6
+
7
+
8
+ __all__ = ["GGUFHeaderError"]
9
+
10
+
11
+ class PathEscape(ValueError):
12
+ """A path resolved outside the confinement root."""
13
+
14
+
15
+ __all__ += ["PathEscape"]
16
+
17
+
18
+ class LocalRequestError(Exception):
19
+ """Fallback request error so a runner / child module is importable and
20
+ py_compile-clean on its own (e.g. a unit test imports ``handle`` directly).
21
+
22
+ The child process INJECTS its own ``RequestError`` class into the runner's
23
+ namespace before serving; that class carries the same ``(status, message)``
24
+ and a ``.body`` dict, so ``raise RequestError(400, …)`` stays catchable.
25
+ """
26
+
27
+ def __init__(self, status: int, message: str, **extra):
28
+ super().__init__(message)
29
+ self.status = int(status)
30
+ self.message = message
31
+ self.extra = extra
32
+
33
+ @property
34
+ def body(self) -> dict:
35
+ err = {
36
+ "message": self.message,
37
+ "type": "invalid_request_error",
38
+ "code": self.status,
39
+ }
40
+ err.update(self.extra)
41
+ return {"error": err}
42
+
43
+
44
+ class ChatRequestError(Exception):
45
+ """An OpenAI-style client error: HTTP ``status`` + error body."""
46
+
47
+ def __init__(
48
+ self, status: int, message: str, etype: str = "invalid_request_error", **extra
49
+ ):
50
+ super().__init__(message)
51
+ self.status = status
52
+ self.body = {
53
+ "error": {"code": status, "type": etype, "message": message, **extra}
54
+ }
55
+
56
+
57
+ class TaskRequestError(Exception):
58
+ """An OpenAI-style client error: HTTP ``status`` + error body. INJECTED into
59
+ the runner module's namespace before use, so a runner raises
60
+ ``RequestError(400, …)`` and it is caught here as a 4xx (never a 500)."""
61
+
62
+ def __init__(
63
+ self, status: int, message: str, etype: str = "invalid_request_error", **extra
64
+ ):
65
+ super().__init__(message)
66
+ self.status = int(status)
67
+ self.message = message
68
+ self.body = {
69
+ "error": {"code": int(status), "type": etype, "message": message, **extra}
70
+ }
71
+
72
+
73
+ class StoreError(RuntimeError):
74
+ """The store could not be opened or migrated."""
@@ -0,0 +1,116 @@
1
+ """HTTP scaffold for engine children."""
2
+
3
+ from __future__ import annotations
4
+ from ..init_imports import json
5
+ from ..init_imports import traceback
6
+ from ..init_imports import BaseHTTPRequestHandler
7
+
8
+
9
+ def _not_found(path: str) -> dict:
10
+ return {
11
+ "error": {"code": 404, "type": "not_found_error", "message": f"no route {path}"}
12
+ }
13
+
14
+
15
+ def make_child_handler(server, request_error_cls, *, chat: bool = True, log=None):
16
+ """Build the ``BaseHTTPRequestHandler`` subclass the child model servers use.
17
+
18
+ Shared across tf_child / vision_child / task_child: ``log_message`` (silent —
19
+ stderr is the loader-log channel), ``_json``, and the GET routes
20
+ (``/health``, ``/v1/models``, ``/props``). With ``chat=True`` (tf/vision) the
21
+ POST route is ``/v1/chat/completions``, errors fall back to a 500 (logged via
22
+ ``log`` if given), and the subclass supplies ``_stream``; with ``chat=False``
23
+ (task) the subclass supplies its own ``do_POST``.
24
+
25
+ ``server`` must expose ``models_doc()``/``props_doc()`` and, for chat,
26
+ ``lock``/``prepare(body)``/``complete(job)``. ``request_error_cls`` is the
27
+ child's injected ``RequestError``; ``log`` is the child's ``_log``.
28
+ """
29
+ RequestError = request_error_cls
30
+
31
+ class _Handler(BaseHTTPRequestHandler):
32
+ protocol_version = "HTTP/1.0"
33
+
34
+ def log_message(self, fmt, *args): # keep the loader log for errors only
35
+ pass
36
+
37
+ def _json(self, status: int, doc: dict) -> None:
38
+ data = json.dumps(doc).encode()
39
+ self.send_response(status)
40
+ self.send_header("Content-Type", "application/json")
41
+ self.send_header("Content-Length", str(len(data)))
42
+ self.end_headers()
43
+ self.wfile.write(data)
44
+
45
+ def do_GET(self):
46
+ path = self.path.split("?", 1)[0]
47
+ if path == "/health":
48
+ return self._json(200, {"status": "ok"})
49
+ if path == "/v1/models":
50
+ return self._json(200, server.models_doc())
51
+ if path == "/props":
52
+ return self._json(200, server.props_doc())
53
+ return self._json(404, _not_found(path))
54
+
55
+ if chat:
56
+
57
+ def do_POST(self):
58
+ path = self.path.split("?", 1)[0]
59
+ if path not in ("/v1/chat/completions", "/tokenize"):
60
+ return self._json(404, _not_found(path))
61
+ try:
62
+ n = int(self.headers.get("Content-Length") or 0)
63
+ body = json.loads(self.rfile.read(n) or b"{}")
64
+ if not isinstance(body, dict):
65
+ raise RequestError(400, "request body must be a JSON object")
66
+ except (ValueError, RequestError) as exc:
67
+ err = (
68
+ exc
69
+ if isinstance(exc, RequestError)
70
+ else RequestError(400, f"bad JSON: {exc}")
71
+ )
72
+ return self._json(err.status, err.body)
73
+ if path == "/tokenize":
74
+ tokenize = getattr(server, "tokenize_doc", None)
75
+ if tokenize is None:
76
+ return self._json(404, _not_found(path))
77
+ if not server.lock.acquire(blocking=False):
78
+ return self._json(
79
+ 409,
80
+ {
81
+ "error": {
82
+ "message": "Tokenizer preflight deferred while the engine is busy"
83
+ }
84
+ },
85
+ )
86
+ try:
87
+ return self._json(200, tokenize(body))
88
+ except RequestError as exc:
89
+ return self._json(exc.status, exc.body)
90
+ except Exception as exc:
91
+ return self._json(400, {"error": {"message": str(exc)}})
92
+ finally:
93
+ server.lock.release()
94
+ with server.lock:
95
+ try:
96
+ job = server.prepare(body)
97
+ if not body.get("stream"):
98
+ return self._json(200, server.complete(job))
99
+ return self._stream(job)
100
+ except RequestError as exc:
101
+ return self._json(exc.status, exc.body)
102
+ except Exception as exc: # noqa: BLE001 — the real error, to the caller and the log
103
+ if log:
104
+ log(traceback.format_exc())
105
+ return self._json(
106
+ 500,
107
+ {
108
+ "error": {
109
+ "code": 500,
110
+ "type": "server_error",
111
+ "message": f"{type(exc).__name__}: {exc}",
112
+ }
113
+ },
114
+ )
115
+
116
+ return _Handler
@@ -0,0 +1,32 @@
1
+ """Reusable nvml definitions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..init_imports import ctypes
6
+
7
+
8
+ class _MemV2(ctypes.Structure):
9
+ _fields_ = [
10
+ ("version", ctypes.c_uint),
11
+ ("total", ctypes.c_ulonglong),
12
+ ("reserved", ctypes.c_ulonglong),
13
+ ("free", ctypes.c_ulonglong),
14
+ ("used", ctypes.c_ulonglong),
15
+ ]
16
+
17
+
18
+ class _Mem(ctypes.Structure):
19
+ _fields_ = [
20
+ ("total", ctypes.c_ulonglong),
21
+ ("free", ctypes.c_ulonglong),
22
+ ("used", ctypes.c_ulonglong),
23
+ ]
24
+
25
+
26
+ class _ProcV3(ctypes.Structure):
27
+ _fields_ = [
28
+ ("pid", ctypes.c_uint),
29
+ ("usedGpuMemory", ctypes.c_ulonglong),
30
+ ("gpuInstanceId", ctypes.c_uint),
31
+ ("computeInstanceId", ctypes.c_uint),
32
+ ]
@@ -0,0 +1,77 @@
1
+ # Streaming sibling of no_think.strip_think: separate a model's <think> reasoning
2
+ # from its answer prose INCREMENTALLY, as content deltas arrive, so the front
3
+ # door can re-emit delta.reasoning_content vs delta.content live. The engine
4
+ # (llama-server --reasoning-format deepseek) usually separates reasoning itself;
5
+ # this is the fallback for inline-tag replies (reasoning-format none / a model
6
+ # whose template leaves <think> tags in message.content).
7
+ #
8
+ # Final-assembly semantics match no_think.strip_think (<think>...</think> blocks
9
+ # and an unclosed <think>...EOF are reasoning). An ORPHAN </think> (a template
10
+ # that opens <think> in the prompt, so the reply starts mid-reasoning with no
11
+ # opening tag) is handled downstream by hugpy_core.grader.strip_think on the
12
+ # assembled text; live, text before an orphan close streams as content and the
13
+ # answer after it streams as content too — the grader's rule salvages the answer.
14
+ """Incremental <think> splitter for streamed content."""
15
+
16
+ from __future__ import annotations
17
+
18
+ from ..constants import THINK_CLOSE_TAG as _CLOSE
19
+ from ..constants import THINK_OPEN_TAG as _OPEN
20
+
21
+
22
+ from ..functions.thinking import _partial_tail
23
+
24
+
25
+ class ThinkSplitter:
26
+ """Feed streamed content text; get back (channel, chunk) pairs where channel
27
+ is 'reasoning' (inside a <think> block) or 'content' (the answer). Holds back
28
+ a short tail when the buffer might end mid-tag, so a tag split across two
29
+ feeds is still recognised."""
30
+
31
+ def __init__(self) -> None:
32
+ self._buf = ""
33
+ self._mode = "content" # 'content' | 'reasoning'
34
+
35
+ def feed(self, text: str) -> "list[tuple[str, str]]":
36
+ out: "list[tuple[str, str]]" = []
37
+ if not text:
38
+ return out
39
+ self._buf += text
40
+ while True:
41
+ low = self._buf.lower()
42
+ i_open = low.find(_OPEN)
43
+ i_close = low.find(_CLOSE)
44
+ cands = [p for p in (i_open, i_close) if p != -1]
45
+ if cands:
46
+ idx = min(cands)
47
+ is_open = idx == i_open
48
+ tag = _OPEN if is_open else _CLOSE
49
+ before = self._buf[:idx]
50
+ if before:
51
+ out.append((self._mode, before))
52
+ self._buf = self._buf[idx + len(tag) :]
53
+ self._mode = "reasoning" if is_open else "content"
54
+ continue
55
+ hold = _partial_tail(self._buf)
56
+ if hold:
57
+ emit = self._buf[: len(self._buf) - hold]
58
+ if emit:
59
+ out.append((self._mode, emit))
60
+ self._buf = self._buf[len(self._buf) - hold :]
61
+ else:
62
+ if self._buf:
63
+ out.append((self._mode, self._buf))
64
+ self._buf = ""
65
+ break
66
+ return out
67
+
68
+ def close(self) -> "list[tuple[str, str]]":
69
+ """Flush whatever is held (a dangling partial tag, treated as text)."""
70
+ out: "list[tuple[str, str]]" = []
71
+ if self._buf:
72
+ out.append((self._mode, self._buf))
73
+ self._buf = ""
74
+ return out
75
+
76
+
77
+ __all__ = ["ThinkSplitter"]
@@ -0,0 +1,53 @@
1
+ """Reusable tool calls definitions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..functions.tool_calls import _calls
6
+ from ..constants import _BLOCK
7
+ from ..constants import DSML_TOOLS_TAGS as _TAGS
8
+
9
+
10
+ class StreamSplitter:
11
+ """Streamed reply: feed() content pieces; yields ("content", text) for prose and
12
+ ("tool_calls", [call, ...]) once a whole block has arrived. Text that may be the
13
+ start of a block is held back until it is known not to be one."""
14
+
15
+ def __init__(self):
16
+ self.buf = ""
17
+ self.emitted = 0 # tool calls sent so far (their stream index)
18
+
19
+ def _hold_from(self) -> int:
20
+ """Index from which the buffer must be held (a block, or a possible tag start)."""
21
+ starts = [i for tag in _TAGS if (i := self.buf.find(tag)) >= 0]
22
+ if starts:
23
+ return min(starts)
24
+ for k in range(min(max(map(len, _TAGS)) - 1, len(self.buf)), 0, -1):
25
+ if any(tag.startswith(self.buf[-k:]) for tag in _TAGS):
26
+ return len(self.buf) - k
27
+ return len(self.buf)
28
+
29
+ def feed(self, piece: str):
30
+ self.buf += piece or ""
31
+ out = []
32
+ while True:
33
+ m = _BLOCK.search(self.buf)
34
+ if m:
35
+ if m.start():
36
+ out.append(("content", self.buf[: m.start()]))
37
+ calls = _calls(m.group(2))
38
+ if calls:
39
+ out.append(("tool_calls", calls))
40
+ else:
41
+ out.append(("content", m.group(0)))
42
+ self.buf = self.buf[m.end() :]
43
+ continue
44
+ cut = self._hold_from()
45
+ if cut:
46
+ out.append(("content", self.buf[:cut]))
47
+ self.buf = self.buf[cut:]
48
+ return out
49
+
50
+ def close(self):
51
+ """End of stream: an unfinished block is passed through as text (never lost)."""
52
+ rest, self.buf = self.buf, ""
53
+ return [("content", rest)] if rest else []
@@ -0,0 +1,45 @@
1
+ """Typed constants projected from terms, exported once by each domain.
2
+
3
+ Domains load together when this projection is first requested. Public exports
4
+ come from their __all__ declarations; no second list of symbols is maintained.
5
+ """
6
+
7
+ from importlib import import_module as _import_module
8
+
9
+ _DOMAINS = (
10
+ 'math',
11
+ 'terms',
12
+ 'platform',
13
+ 'formats',
14
+ 'gguf',
15
+ 'tensors',
16
+ 'architecture',
17
+ 'memory',
18
+ 'hardware',
19
+ 'engines',
20
+ 'text',
21
+ 'tool_calls',
22
+ 'identity',
23
+ 'transfer',
24
+ 'comfy',
25
+ 'placement',
26
+ 'cpu',
27
+ 'context',
28
+ 'admission',
29
+ 'validation',
30
+ 'drives',
31
+ 'timing',
32
+ 'audit',
33
+ )
34
+
35
+ __all__ = []
36
+ for _domain_name in _DOMAINS:
37
+ _domain = _import_module(f"{__name__}.{_domain_name}")
38
+ globals()[_domain_name] = _domain
39
+ for _name in _domain.__all__:
40
+ if _name in __all__:
41
+ raise ValueError(f"duplicate constant export: {_name}")
42
+ globals()[_name] = getattr(_domain, _name)
43
+ __all__.append(_name)
44
+
45
+ del _domain_name, _domain, _name
@@ -0,0 +1,19 @@
1
+ """Admission projections of terms.json; authored values belong to terms."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .terms import value as _value, group as _group
6
+
7
+ from .terms import knob_schema
8
+
9
+ RESIDENCY_MODES = _value('admission', 'residency_modes')
10
+
11
+ ADMISSION_KNOB_TERMS = _group('admission_knobs')
12
+
13
+ ADMISSION_KNOB_SCHEMA = knob_schema(ADMISSION_KNOB_TERMS)
14
+
15
+ __all__ = [
16
+ 'RESIDENCY_MODES',
17
+ 'ADMISSION_KNOB_TERMS',
18
+ 'ADMISSION_KNOB_SCHEMA',
19
+ ]
@@ -0,0 +1,84 @@
1
+ """Architecture projections of terms.json; authored values belong to terms."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .terms import value as _value, group as _group
6
+
7
+ TRANSFORMERS_GATED_DELTA = _value('architecture', 'transformers_gated_delta')
8
+
9
+
10
+ NO_CONTEXT_HEADS = _value('architecture', 'no_context_heads')
11
+
12
+
13
+ DENSE_DECODERS = _value('architecture', 'dense_decoders')
14
+
15
+
16
+ MOE_DECODERS = _value('architecture', 'moe_decoders')
17
+
18
+
19
+ DTYPE_BITS = {key: term["bits"] for key, term in _group("tensor_dtypes").items()}
20
+
21
+ RECURRENT_COUNT_FIELDS = _value('architecture', 'recurrent_count_fields')
22
+
23
+ TEXT_CONFIG_KEYS = _value('architecture', 'text_config_keys')
24
+
25
+ DECODER_LAYER_KEYS = _value('architecture', 'decoder_layer_keys')
26
+
27
+ MODEL_LAYER_KEYS = _value('architecture', 'model_layer_keys')
28
+
29
+ DECODER_ATTENTION_HEAD_KEYS = _value('architecture', 'decoder_attention_head_keys')
30
+
31
+ ATTENTION_HEAD_KEYS = _value('architecture', 'attention_head_keys')
32
+
33
+ KV_HEAD_KEYS = _value('architecture', 'kv_head_keys')
34
+
35
+ HEAD_DIM_KEYS = _value('architecture', 'head_dim_keys')
36
+
37
+ HIDDEN_SIZE_KEYS = _value('architecture', 'hidden_size_keys')
38
+
39
+ ATTENTION_LAYER_TYPES = _value('architecture', 'attention_layer_types')
40
+
41
+ RECURRENT_LAYER_TYPES = _value('architecture', 'recurrent_layer_types')
42
+
43
+ RECURRENT_MODEL_TYPES = _value('architecture', 'recurrent_model_types')
44
+
45
+ CONTEXT_LENGTH_KEYS = _value('architecture', 'context_length_keys')
46
+
47
+ LINEAR_STATE_KEYS = _value('architecture', 'linear_state_keys')
48
+
49
+ UNSUPPORTED_OUTPUT_FLAGS = _value('architecture', 'unsupported_output_flags')
50
+
51
+ EXPERT_COUNT_KEYS = _value('architecture', 'expert_count_keys')
52
+
53
+ RUNTIME_DENSE_GEOMETRY_FIELDS = _value('architecture', 'runtime_dense_geometry_fields')
54
+
55
+ RUNTIME_EXPERT_GEOMETRY_FIELDS = _value('architecture', 'runtime_expert_geometry_fields')
56
+
57
+ RUNTIME_DENSE_DTYPES = _value('architecture', 'runtime_dense_dtypes')
58
+
59
+ __all__ = [
60
+ 'TRANSFORMERS_GATED_DELTA',
61
+ 'NO_CONTEXT_HEADS',
62
+ 'DENSE_DECODERS',
63
+ 'MOE_DECODERS',
64
+ 'DTYPE_BITS',
65
+ 'RECURRENT_COUNT_FIELDS',
66
+ 'TEXT_CONFIG_KEYS',
67
+ 'DECODER_LAYER_KEYS',
68
+ 'MODEL_LAYER_KEYS',
69
+ 'DECODER_ATTENTION_HEAD_KEYS',
70
+ 'ATTENTION_HEAD_KEYS',
71
+ 'KV_HEAD_KEYS',
72
+ 'HEAD_DIM_KEYS',
73
+ 'HIDDEN_SIZE_KEYS',
74
+ 'ATTENTION_LAYER_TYPES',
75
+ 'RECURRENT_LAYER_TYPES',
76
+ 'RECURRENT_MODEL_TYPES',
77
+ 'CONTEXT_LENGTH_KEYS',
78
+ 'LINEAR_STATE_KEYS',
79
+ 'UNSUPPORTED_OUTPUT_FLAGS',
80
+ 'EXPERT_COUNT_KEYS',
81
+ 'RUNTIME_DENSE_GEOMETRY_FIELDS',
82
+ 'RUNTIME_EXPERT_GEOMETRY_FIELDS',
83
+ 'RUNTIME_DENSE_DTYPES',
84
+ ]
@@ -0,0 +1,6 @@
1
+ """Audit and row-history projections of terms.json."""
2
+ from .terms import value as _value
3
+ HISTORY_TABLE = _value('audit', 'history_table')
4
+ VOLATILE_COLUMNS = _value('audit', 'history_volatile_columns')
5
+ HISTORY_CHUNK = _value('audit', 'history_chunk')
6
+ __all__ = ['HISTORY_TABLE', 'VOLATILE_COLUMNS', 'HISTORY_CHUNK']
@@ -0,0 +1,15 @@
1
+ """Comfy projections of terms.json; authored values belong to terms."""
2
+
3
+ from .terms import value as _value
4
+
5
+ COMFY_REFERENCE_FAMILIES = _value('comfy', 'comfy_reference_families')
6
+
7
+ COMFY_REFERENCE_FIELDS = _value('comfy', 'comfy_reference_fields')
8
+
9
+ COMFY_REFERENCE_FILE_FIELDS = _value('comfy', 'comfy_reference_file_fields')
10
+
11
+ __all__ = [
12
+ 'COMFY_REFERENCE_FAMILIES',
13
+ 'COMFY_REFERENCE_FIELDS',
14
+ 'COMFY_REFERENCE_FILE_FIELDS',
15
+ ]
@@ -0,0 +1,37 @@
1
+ """Context projections of terms.json; authored values belong to terms."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .terms import value as _value, group as _group
6
+
7
+ from .terms import knob_schema
8
+
9
+ CONTEXT_PERCENT_KNOBS = _value('context', 'context_percent_knobs')
10
+
11
+ KV_CACHE_TYPES = _value('context', 'kv_cache_types')
12
+
13
+ CONTEXT_PRESETS = _value('context', 'context_presets')
14
+
15
+ CONTEXT_PERCENT_MIN = _value('context', 'context_percent_min')
16
+
17
+ PAIR_KNOB_RENAMES = _value('context', 'pair_knob_renames')
18
+
19
+ CONTEXT_KNOB_TERMS = _group('context_knobs')
20
+
21
+ CONTEXT_KNOB_SCHEMA = knob_schema(CONTEXT_KNOB_TERMS)
22
+
23
+ # Derived from the schema so they can never drift from the context knobs themselves.
24
+ CONTEXT_KEYS = tuple(knob["key"] for knob in CONTEXT_KNOB_SCHEMA)
25
+ CONTEXT_BOOLEAN_KNOBS = tuple(knob["key"] for knob in CONTEXT_KNOB_SCHEMA if knob["type"] == "bool")
26
+
27
+ __all__ = [
28
+ 'CONTEXT_PERCENT_KNOBS',
29
+ 'KV_CACHE_TYPES',
30
+ 'CONTEXT_PRESETS',
31
+ 'CONTEXT_PERCENT_MIN',
32
+ 'PAIR_KNOB_RENAMES',
33
+ 'CONTEXT_KNOB_TERMS',
34
+ 'CONTEXT_KNOB_SCHEMA',
35
+ 'CONTEXT_KEYS',
36
+ 'CONTEXT_BOOLEAN_KNOBS',
37
+ ]