@meridiona/meridian-darwin-arm64 1.66.0 → 1.66.1

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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.66.0
1
+ 1.66.1
package/bin/meridian CHANGED
Binary file
package/bin/meridian-tray CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridiona/meridian-darwin-arm64",
3
- "version": "1.66.0",
3
+ "version": "1.66.1",
4
4
  "description": "Prebuilt Meridian app for macOS arm64 (daemon binary + dashboard + Python services). Installed via @meridiona/meridian.",
5
5
  "homepage": "https://github.com/Meridiona/meridian",
6
6
  "repository": {
@@ -13,7 +13,7 @@ app_state: dict[str, Any] = {}
13
13
  # `received`/`total` are AGGREGATE byte counts summed across every pipeline model
14
14
  # (llm + reranker + embedder), so the wizard's progress bar has a single honest
15
15
  # denominator. The wire contract the Rust tray decodes is exactly
16
- # state/received/total/error (tray/src-tauri/src/mlx_server.rs::PrefetchStatus);
16
+ # state/received/total/error/speed (tray/src-tauri/src/mlx_server.rs::PrefetchStatus);
17
17
  # `models` is an additive per-model breakdown the tray ignores.
18
18
  prefetch_state: dict[str, Any] = {
19
19
  "state": "idle",
@@ -33,10 +33,9 @@ router = APIRouter()
33
33
  # Speed is derived from the growth of on-disk `received` between /prefetch_status
34
34
  # polls — NOT from a tqdm hook. hf_xet (the Xet accelerator these models use) does
35
35
  # its download in Rust and bypasses the classic tqdm bar, so a tqdm_class never
36
- # fires; the byte-delta approach works for any backend. These hold the last
37
- # (received, monotonic-time) sample to diff against.
38
- _last_recv = 0
39
- _last_recv_ts = 0.0
36
+ # fires; the byte-delta approach works for any backend. Stored as a dict so both
37
+ # functions can mutate it in-place without `global` declarations.
38
+ _speed_state: dict[str, float | int] = {"recv": 0, "ts": 0.0}
40
39
 
41
40
 
42
41
  def _hf_cache_dir_for(model_id: str) -> Path:
@@ -140,7 +139,7 @@ def _run_prefetch(specs: list[model_registry.ModelSpec]) -> None:
140
139
  prefetch_state["error"] = str(exc)
141
140
  prefetch_state["speed"] = 0.0
142
141
  root.set_status(trace.Status(trace.StatusCode.ERROR, str(exc)))
143
- log.error("server: model prefetch failed", extra={"error": str(exc)})
142
+ log.exception("server: model prefetch failed", extra={"error": str(exc)})
144
143
 
145
144
 
146
145
  @router.post("/prefetch_model")
@@ -160,13 +159,13 @@ async def prefetch_model() -> dict:
160
159
 
161
160
  from fastapi.concurrency import run_in_threadpool
162
161
 
163
- global _last_recv, _last_recv_ts
164
162
  specs = list(model_registry.ALL_SPECS)
165
163
 
166
164
  with prefetch_lock:
167
165
  if prefetch_state["state"] in ("downloading", "done"):
168
166
  return dict(prefetch_state) # idempotent — no duplicate downloads
169
- _last_recv, _last_recv_ts = 0, 0.0
167
+ _speed_state["recv"] = 0
168
+ _speed_state["ts"] = 0.0
170
169
  prefetch_state.update(
171
170
  state="downloading",
172
171
  received=0,
@@ -189,7 +188,7 @@ async def prefetch_model() -> dict:
189
188
  return_exceptions=True,
190
189
  )
191
190
  totals: list[int] = []
192
- for spec, r in zip(specs, probe_results):
191
+ for spec, r in zip(specs, probe_results, strict=True):
193
192
  if isinstance(r, int):
194
193
  totals.append(r)
195
194
  else:
@@ -223,7 +222,6 @@ async def prefetch_status() -> dict:
223
222
  """
224
223
  from fastapi.concurrency import run_in_threadpool
225
224
 
226
- global _last_recv, _last_recv_ts
227
225
  with prefetch_lock:
228
226
  st = dict(prefetch_state)
229
227
  models = list(st.get("models", []))
@@ -252,12 +250,13 @@ async def prefetch_status() -> dict:
252
250
  # EMA-smoothed; decays to 0 when bytes stop flowing (delta 0) or the run ends.
253
251
  now = time.monotonic()
254
252
  with prefetch_lock:
255
- if st["state"] == "downloading" and _last_recv_ts and now > _last_recv_ts:
256
- inst = max(0, st["received"] - _last_recv) / (now - _last_recv_ts)
253
+ if st["state"] == "downloading" and _speed_state["ts"] and now > _speed_state["ts"]:
254
+ inst = max(0, st["received"] - _speed_state["recv"]) / (now - _speed_state["ts"])
257
255
  prev = prefetch_state.get("speed", 0.0) or 0.0
258
256
  prefetch_state["speed"] = inst if prev == 0.0 else prev * 0.5 + inst * 0.5
259
257
  elif st["state"] != "downloading":
260
258
  prefetch_state["speed"] = 0.0
261
- _last_recv, _last_recv_ts = st["received"], now
259
+ _speed_state["recv"] = st["received"]
260
+ _speed_state["ts"] = now
262
261
  st["speed"] = prefetch_state["speed"]
263
262
  return st
@@ -96,7 +96,7 @@ _ENTITY_RESCUE_CAP = 4
96
96
  _embedder = None # cached (model, tokenizer) tuple
97
97
 
98
98
 
99
- def _get_embedder():
99
+ def _get_embedder() -> tuple:
100
100
  global _embedder
101
101
  if _embedder is None:
102
102
  import mlx_embeddings
@@ -135,7 +135,8 @@ def evict_embedder() -> None:
135
135
  _embedder = None
136
136
  gc.collect()
137
137
  try:
138
- import mlx.core as mx; mx.clear_cache()
138
+ import mlx.core as mx
139
+ mx.clear_cache()
139
140
  except Exception: # noqa: BLE001 — cache flush is best-effort; non-fatal if mlx absent
140
141
  pass
141
142
  log.info("session_distiller: embedding model evicted from memory")
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "meridian-agents"
7
- version = "1.66.0"
7
+ version = "1.66.1"
8
8
  description = "Meridian agents — MLX classifier server and Jira worklog synthesis for meridian.db"
9
9
  requires-python = ">=3.11"
10
10
  authors = [{ name = "Meridiona" }]