hugpy-engine 0.3.4__tar.gz → 0.3.6__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.
Files changed (44) hide show
  1. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/PKG-INFO +1 -1
  2. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/pyproject.toml +1 -1
  3. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/task_endpoints.py +2 -1
  4. hugpy_engine-0.3.6/src/hugpy_engine/utils/__init__.py +1 -0
  5. hugpy_engine-0.3.6/src/hugpy_engine/utils/json_scavenge.py +111 -0
  6. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine.egg-info/PKG-INFO +1 -1
  7. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine.egg-info/SOURCES.txt +3 -1
  8. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/README.md +0 -0
  9. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/setup.cfg +0 -0
  10. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/__init__.py +0 -0
  11. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/categories.py +0 -0
  12. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/config/__init__.py +0 -0
  13. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/config/main.py +0 -0
  14. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/config/models/__init__.py +0 -0
  15. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/config/models/models_config.py +0 -0
  16. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/config/models/models_default.py +0 -0
  17. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/dispatch/__init__.py +0 -0
  18. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/dispatch/dispatch.py +0 -0
  19. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/fit/__init__.py +0 -0
  20. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/fit/types.py +0 -0
  21. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/llama/__init__.py +0 -0
  22. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/llama/runners/__init__.py +0 -0
  23. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/llama/runners/fitevict_runner.py +0 -0
  24. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/name_match.py +0 -0
  25. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/placement.py +0 -0
  26. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/py.typed +0 -0
  27. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/resolvers/__init__.py +0 -0
  28. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/resolvers/assure_model_key.py +0 -0
  29. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/resolvers/categories/__init__.py +0 -0
  30. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/resolvers/categories/builders.py +0 -0
  31. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/resolvers/categories/frameworks.py +0 -0
  32. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/resolvers/model_resolver.py +0 -0
  33. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/__init__.py +0 -0
  34. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/chat_schemas.py +0 -0
  35. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/event_schemas.py +0 -0
  36. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/metadata_schemas.py +0 -0
  37. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/model_schemas.py +0 -0
  38. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/runner_schemas.py +0 -0
  39. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/schemas/task_schemas.py +0 -0
  40. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/task_deps.py +0 -0
  41. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine/tasks.py +0 -0
  42. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine.egg-info/dependency_links.txt +0 -0
  43. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine.egg-info/requires.txt +0 -0
  44. {hugpy_engine-0.3.4 → hugpy_engine-0.3.6}/src/hugpy_engine.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hugpy-engine
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Hugpy engine: model discovery and classification, allocation and eviction, native llama.cpp and GGUF runners, and the prompt-to-reply inference path with task and placement seams
5
5
  Author-email: putkoff <support@hugpy.ai>
6
6
  License-Expression: LicenseRef-Proprietary
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hugpy-engine"
7
- version = "0.3.4"
7
+ version = "0.3.6"
8
8
  description = "Hugpy engine: model discovery and classification, allocation and eviction, native llama.cpp and GGUF runners, and the prompt-to-reply inference path with task and placement seams"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -113,7 +113,8 @@ _BODY_SPECS: dict[str, dict] = {
113
113
  "/v1/videos/generations": {
114
114
  "input_key": "prompt", "sources": ("prompt", "input", "text"),
115
115
  "passthrough": ("num_frames", "fps", "seed", "width", "height", "steps",
116
- "num_inference_steps", "image", "negative_prompt"),
116
+ "num_inference_steps", "guidance_scale", "image", "image_b64",
117
+ "negative_prompt", "response_format"),
117
118
  },
118
119
  }
119
120
 
@@ -0,0 +1 @@
1
+ """Shared helpers for consuming model responses."""
@@ -0,0 +1,111 @@
1
+ """JSON SCAVENGER — recover a well-formed JSON value from a model reply.
2
+
3
+ WHY THIS EXISTS AS A SHARED SEAM
4
+ --------------------------------
5
+ Two independent copies of this logic already existed in the package —
6
+ ``review/judge.py:_extract_json`` (object, fence + brace-balance walk) and
7
+ ``comms/todo_keeper.py:_extract_json_array`` (array, whole-string / fence /
8
+ outermost-span) — written months apart for the same reason: **small local models
9
+ wrap JSON in prose or a ```json fence however firmly you tell them not to.** The
10
+ studio spread path (``video_intel/prompt_spread.py``) needed the same thing, and
11
+ a THIRD copy is where the behaviours quietly diverge. So the two originals now
12
+ delegate here and this module is the single definition.
13
+
14
+ WHAT IT IS NOT
15
+ --------------
16
+ This is recovery of a WELL-FORMED value that arrived with GARNISH — never a
17
+ tolerance for malformed content, and never a repair. Both entry points return
18
+ ``None`` on failure so the caller can degrade HONESTLY (an error naming the
19
+ model and carrying the raw text), which is the whole point: a scavenger that
20
+ guesses would fabricate content the model never produced.
21
+
22
+ STRIP ``<think>`` FIRST. A reasoning block is this failure at its worst — it can
23
+ consume the entire token budget before the JSON starts, and it frequently
24
+ contains braces of its own that the brace walk would happily lock onto. Callers
25
+ run ``utils.no_think.strip_think`` before handing text here; that ordering is
26
+ load-bearing, not decorative.
27
+ """
28
+
29
+ from __future__ import annotations
30
+
31
+ import json
32
+ import re
33
+ from typing import Any, Optional
34
+
35
+ __all__ = ["extract_json_object", "extract_json_array", "extract_json_value"]
36
+
37
+ #: A fenced block, with or without the ``json`` info string. Non-greedy so the
38
+ #: FIRST fence wins when a chatty model emits several.
39
+ _OBJ_FENCE_RE = re.compile(r"```(?:json)?\s*(\{.*?\})\s*```", re.S)
40
+ _ANY_FENCE_RE = re.compile(r"```(?:json)?\s*(.*?)\s*```", re.S)
41
+
42
+
43
+ def extract_json_object(text: str) -> Optional[dict]:
44
+ """Pull the first parseable JSON OBJECT out of ``text``; ``None`` if none.
45
+
46
+ Tries a fenced ``{...}`` block, then walks every ``{`` in the string doing a
47
+ brace-depth scan to find its balanced partner. The walk (rather than
48
+ ``find('{')`` + ``rfind('}')``) is what survives a preamble that itself
49
+ contains braces — it simply moves on to the next candidate opener.
50
+ """
51
+ if not isinstance(text, str) or not text.strip():
52
+ return None
53
+ fence = _OBJ_FENCE_RE.search(text)
54
+ if fence:
55
+ text = fence.group(1)
56
+ start = text.find("{")
57
+ while start != -1:
58
+ depth = 0
59
+ for i in range(start, len(text)):
60
+ if text[i] == "{":
61
+ depth += 1
62
+ elif text[i] == "}":
63
+ depth -= 1
64
+ if depth == 0:
65
+ try:
66
+ parsed = json.loads(text[start:i + 1])
67
+ except ValueError:
68
+ break
69
+ if isinstance(parsed, dict):
70
+ return parsed
71
+ break
72
+ start = text.find("{", start + 1)
73
+ return None
74
+
75
+
76
+ def extract_json_array(text: str, accept_lone_object: bool = True) -> Optional[list]:
77
+ """Pull a JSON ARRAY out of ``text``; ``None`` if none.
78
+
79
+ Candidates in order: the whole string, a fenced block, the outermost
80
+ ``[...]`` span. ``accept_lone_object`` keeps ``todo_keeper``'s long-standing
81
+ near-miss tolerance — a model that returned ONE object where a list of one
82
+ was asked for is wrapped rather than refused. Set it False when a bare object
83
+ should be a failure.
84
+ """
85
+ if not isinstance(text, str) or not text.strip():
86
+ return None
87
+ candidates = [text.strip()]
88
+ m = _ANY_FENCE_RE.search(text)
89
+ if m:
90
+ candidates.append(m.group(1).strip())
91
+ start, end = text.find("["), text.rfind("]")
92
+ if start != -1 and end > start:
93
+ candidates.append(text[start:end + 1])
94
+ for cand in candidates:
95
+ try:
96
+ parsed = json.loads(cand)
97
+ except Exception:
98
+ continue
99
+ if isinstance(parsed, list):
100
+ return parsed
101
+ if accept_lone_object and isinstance(parsed, dict):
102
+ return [parsed]
103
+ return None
104
+
105
+
106
+ def extract_json_value(text: str) -> Any:
107
+ """Object first, else array. For callers that accept either shape."""
108
+ obj = extract_json_object(text)
109
+ if obj is not None:
110
+ return obj
111
+ return extract_json_array(text, accept_lone_object=False)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hugpy-engine
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Hugpy engine: model discovery and classification, allocation and eviction, native llama.cpp and GGUF runners, and the prompt-to-reply inference path with task and placement seams
5
5
  Author-email: putkoff <support@hugpy.ai>
6
6
  License-Expression: LicenseRef-Proprietary
@@ -37,4 +37,6 @@ src/hugpy_engine/schemas/event_schemas.py
37
37
  src/hugpy_engine/schemas/metadata_schemas.py
38
38
  src/hugpy_engine/schemas/model_schemas.py
39
39
  src/hugpy_engine/schemas/runner_schemas.py
40
- src/hugpy_engine/schemas/task_schemas.py
40
+ src/hugpy_engine/schemas/task_schemas.py
41
+ src/hugpy_engine/utils/__init__.py
42
+ src/hugpy_engine/utils/json_scavenge.py
File without changes
File without changes