Skip to content

Merge #38: configurable embedding probe timeout - #41

Merged
jayzeng merged 3 commits into
mainfrom
merge/pr-38-resolved
Sep 20, 2026
Merged

jayzeng merged 3 commits into
mainfrom
merge/pr-38-resolved

Conversation

@jayzeng

@jayzeng jayzeng commented Sep 20, 2026

Copy link
Copy Markdown
Owner

Conflict-resolution PR for #38 after #35 landed. Preserves both histories and keeps the #38 behavior/tests while retaining the exit-summary reasoning-effort changes from #35.

Jinserk Baik and others added 3 commits September 5, 2026 17:13
`memory_status` reported `Embeddings: ? unknown` on healthy setups where
qmd, the models, and semantic search all worked correctly.

`probeEmbeddings()` raced `qmd vsearch` against a hardcoded 4000ms timer.
That probe is not cheap: it runs LLM query expansion plus an embed and
rerank pass. Measured latency on a working install (n=12, warm, idle):

    min 2.35s   median 2.91s   max 3.55s

That leaves only ~0.45s of headroom. Writes schedule a background
`qmd update`/`qmd embed`, which competes for CPU and the embedding model,
so the probe crosses 4s exactly when a write just happened - which is
when users are most likely to run `memory_status`. Reproduced against
real qmd with a concurrent re-index:

    old hardcoded 4s   -> unknown  4005ms
    new default 15s    -> ready    6048ms

The `catch` maps any failure to "unknown", so a slow probe was
indistinguishable from a broken one and the status output implied the
embeddings were at fault when they were fine.

Also note `PI_MEMORY_QMD_SEARCH_TIMEOUT_MS` did not apply here: real
searches honor it, but the probe's literal `4_000` overrode it, so the
knob that looked like it should fix this had no effect.

Changes:
- add DEFAULT_EMBED_PROBE_TIMEOUT_MS (15s) and getEmbedProbeTimeoutMs(),
  overridable via PI_MEMORY_EMBED_PROBE_TIMEOUT_MS
- pass the probe budget to runQmdSearch via an optional timeout override
  so an abandoned probe cannot leave a 60s LLM query running
- surface the effective timeout in the "unknown" hint and in the
  memory_status configuration block
- document the variable in README.md

Considered parsing `qmd status` instead, since it needs no LLM and is
~14x faster (0.21s vs 2.91s). Rejected: its `Vectors: N embedded` count
is index-global, not per-collection, so it would report "ready" from
another collection's embeddings while pi-memory had none. `qmd status`
also has no --json mode, making the parse fragile. Correctness over speed.

Tests: 8 new cases covering the default floor, env override, invalid
values, ready/missing detection, child-process bounding, and a genuine
timeout still yielding "unknown". Verified red/green: reverting only the
probe change fails 3 of them.

  bun test test/unit.test.ts   190 pass, 0 fail (was 182 pass)
  npm run build                clean
  npm run lint                 clean

No change to on-disk memory formats. qmd invocation is unchanged apart
from the child timeout value.

Signed-off-by: Jinserk Baik <jvby@novonordisk.com>
@jayzeng
jayzeng merged commit 482bcf3 into main Sep 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant