Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,22 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.12"]
mcp-version: [minimum, latest]
pydantic-version: [latest]
include:
- os: ubuntu-latest
python-version: "3.10"
mcp-version: minimum
pydantic-version: latest
# Exercise the MCP/Pydantic floor pair and the release that removed
# eval_type_backport. Other dependencies still use normal resolution.
- os: ubuntu-latest
python-version: "3.10"
mcp-version: minimum
pydantic-version: "2.11.0"
- os: ubuntu-latest
python-version: "3.12"
mcp-version: minimum
pydantic-version: "2.14.0"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -149,6 +161,7 @@ jobs:
shell: python
env:
MCP_VERSION: ${{ matrix.mcp-version }}
PYDANTIC_VERSION: ${{ matrix.pydantic-version }}
run: |
import os
from pathlib import Path
Expand All @@ -161,7 +174,9 @@ jobs:
python = env_dir / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
requirements = [str(wheel.resolve())]
if os.environ["MCP_VERSION"] == "minimum":
requirements.append("mcp[cli]==1.19.0")
requirements.append("mcp[cli]==1.21.1")
if os.environ["PYDANTIC_VERSION"] != "latest":
requirements.append("pydantic==" + os.environ["PYDANTIC_VERSION"])
subprocess.run([str(python), "-m", "pip", "install", *requirements], check=True)
subprocess.run([str(python), "-m", "pip", "check"], check=True)
subprocess.run([str(python), "-I", "tests/mcp-wheel-smoke.py"], check=True)
11 changes: 10 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ jobs:
fail-fast: false
matrix:
mcp-version: [minimum, latest]
pydantic-version: [latest]
include:
- mcp-version: minimum
pydantic-version: "2.11.0"
- mcp-version: minimum
pydantic-version: "2.14.0"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
Expand All @@ -54,6 +60,7 @@ jobs:
shell: python
env:
MCP_VERSION: ${{ matrix.mcp-version }}
PYDANTIC_VERSION: ${{ matrix.pydantic-version }}
run: |
import os
from pathlib import Path
Expand All @@ -66,7 +73,9 @@ jobs:
python = env_dir / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
requirements = [str(wheel.resolve())]
if os.environ["MCP_VERSION"] == "minimum":
requirements.append("mcp[cli]==1.19.0")
requirements.append("mcp[cli]==1.21.1")
if os.environ["PYDANTIC_VERSION"] != "latest":
requirements.append("pydantic==" + os.environ["PYDANTIC_VERSION"])
subprocess.run([str(python), "-m", "pip", "install", *requirements], check=True)
subprocess.run([str(python), "-m", "pip", "check"], check=True)
subprocess.run([str(python), "-I", "tests/mcp-wheel-smoke.py"], check=True)
Expand Down
35 changes: 35 additions & 0 deletions docs/resource-budgets.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,38 @@ It does not change the tier worker's adaptive/OOM policy, models, precision
or retrieval depth. The initial comparison's numerical failures and latency
regressions remain recorded until separate native validation resolves them.
Linux/CUDA behavior does not establish MPS memory or thermal performance.

## Server target identity prerequisite (#795)

An explicit embedding request no longer changes the daemon's default model,
dimension or generation. The same raw tier keeps its loaded snapshot, including
an empty tier whose default changed while its initial load was in progress.
Main and fast requests retain that captured identity. A cache miss or a
different tier request resolves the current selection; changing the global
default alone does not invalidate an already published empty-tier snapshot.
`base`, `pro` and `qwen3_256` reuse the same loaded Qwen3 instance; `edge` and
`model2vec` reuse the same loaded Model2Vec instance. These are the two
deterministic identities already allowed by the fast lane. Alias updates
publish one immutable cache snapshot. A failed distinct load preserves the
previous snapshot.

The removed `qwen3` name still raises the existing migration error, including
case and whitespace variants. This validation does not mutate the default or
adopt broader alias normalization from the active-model setter.

Explicit custom and other configuration-dependent cache entries retain their
existing raw-key reuse policy, including a custom entry that loaded a built-in
identity or Model2Vec fallback before its configuration changed. They gain no
new identity or dimension attestation, and the legacy server fallback for `minilm` and `bge-small`
remains unchanged. Result-size preflight uses the same cache-selection rule
as loading. Fast-lane inference continues to follow its captured loaded-model
snapshot, without resolving current global settings.

This correction preserves inference/state lock ownership, request deadlines,
native batch ceilings and sticky CPU recovery. It does not bound the lifetime
of separately retained old model references: the previous main instance can
still be alive while a distinct replacement is constructed, and the optional
fast CPU instance remains separately owned. A managed preparation lifetime and
an explicit protocol guarantee for older daemons are subsequent prerequisites.
No tier-switch caller, local loader, target table or active configuration is
changed by this checkpoint; issue #795 remains open.
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ dependencies = [
"model2vec>=0.6.0,<1.0",
"sqlite-vec>=0.1.0,<1.0",
"numpy>=1.24.0,<3.0",
# Tool metadata requires 1.19; SDK 2 removes the FastMCP import path.
"mcp[cli]>=1.19.0,<2.0",
# 1.21.1 removes a private Pydantic import broken by Pydantic 2.14.
# SDK 2 removes the FastMCP import path.
"mcp[cli]>=1.21.1,<2.0",
"httpx>=0.27.0,<1.0",
"sentence-transformers>=3.0.0,<7.0",
"torch>=2.0.0,<3.0",
Expand Down
10 changes: 10 additions & 0 deletions tests/mcp-wheel-smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ async def _check_protocol(root: Path, env: dict[str, str], origin: Path) -> None
def main() -> None:
_require(bool(sys.flags.isolated), "Run this probe with python -I")
distribution = importlib.metadata.distribution("truememory")
# Report public package versions before subprocess checks, whose output is
# intentionally redacted. Dependency import failures then remain traceable.
print(json.dumps({
"stage": "dependency_versions",
"python_version": ".".join(str(part) for part in sys.version_info[:3]),
"truememory_version": distribution.version,
"mcp_version": importlib.metadata.version("mcp"),
"pydantic_version": importlib.metadata.version("pydantic"),
"pydantic_core_version": importlib.metadata.version("pydantic-core"),
}), flush=True)
origin = Path(distribution.locate_file("truememory/__init__.py")).resolve()
spec = importlib.util.find_spec("truememory")
_require(origin.is_file() and spec is not None and spec.origin is not None,
Expand Down
Loading
Loading