Spaces:
Paused
Paused
Merge pull request #2 from will-rice/perf/deferred-review-followups
Browse filesDeferred review follow-ups: bake embedding model, cap list_recent days
- Dockerfile +3 -0
- src/papers_mcp/server.py +3 -2
- tests/test_server.py +9 -0
- uv.lock +2 -0
Dockerfile
CHANGED
|
@@ -13,6 +13,9 @@ WORKDIR /app
|
|
| 13 |
|
| 14 |
COPY --chown=user pyproject.toml uv.lock ./
|
| 15 |
RUN uv sync --frozen --no-dev --no-install-project
|
|
|
|
|
|
|
|
|
|
| 16 |
COPY --chown=user . .
|
| 17 |
RUN uv sync --frozen --no-dev
|
| 18 |
|
|
|
|
| 13 |
|
| 14 |
COPY --chown=user pyproject.toml uv.lock ./
|
| 15 |
RUN uv sync --frozen --no-dev --no-install-project
|
| 16 |
+
# Bake the embedding model into the image so startup doesn't hit the HF Hub.
|
| 17 |
+
RUN uv run --no-sync python -c "from sentence_transformers import SentenceTransformer; \
|
| 18 |
+
SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2', device='cpu')"
|
| 19 |
COPY --chown=user . .
|
| 20 |
RUN uv sync --frozen --no-dev
|
| 21 |
|
src/papers_mcp/server.py
CHANGED
|
@@ -26,6 +26,7 @@ CORPORA = {
|
|
| 26 |
DATA_DIR = Path("data")
|
| 27 |
REFRESH_INTERVAL_SECONDS = 6 * 60 * 60
|
| 28 |
MAX_SEARCH_LIMIT = 50
|
|
|
|
| 29 |
|
| 30 |
corpora: dict[str, Corpus] = {}
|
| 31 |
indexes: dict[str, SearchIndex] = {}
|
|
@@ -128,8 +129,8 @@ def make_server(name: str) -> FastMCP:
|
|
| 128 |
@mcp.tool()
|
| 129 |
def list_recent(days: int = 30) -> str:
|
| 130 |
"""List papers submitted in the last N days, newest first."""
|
| 131 |
-
if days <
|
| 132 |
-
raise ValueError("days must be
|
| 133 |
cutoff = (date.today() - timedelta(days=days)).isoformat()
|
| 134 |
recent = sorted(
|
| 135 |
(p for p in corpora[name].papers.values() if p.submitted >= cutoff),
|
|
|
|
| 26 |
DATA_DIR = Path("data")
|
| 27 |
REFRESH_INTERVAL_SECONDS = 6 * 60 * 60
|
| 28 |
MAX_SEARCH_LIMIT = 50
|
| 29 |
+
MAX_RECENT_DAYS = 365
|
| 30 |
|
| 31 |
corpora: dict[str, Corpus] = {}
|
| 32 |
indexes: dict[str, SearchIndex] = {}
|
|
|
|
| 129 |
@mcp.tool()
|
| 130 |
def list_recent(days: int = 30) -> str:
|
| 131 |
"""List papers submitted in the last N days, newest first."""
|
| 132 |
+
if not 1 <= days <= MAX_RECENT_DAYS:
|
| 133 |
+
raise ValueError(f"days must be between 1 and {MAX_RECENT_DAYS}")
|
| 134 |
cutoff = (date.today() - timedelta(days=days)).isoformat()
|
| 135 |
recent = sorted(
|
| 136 |
(p for p in corpora[name].papers.values() if p.submitted >= cutoff),
|
tests/test_server.py
CHANGED
|
@@ -97,3 +97,12 @@ def test_list_recent_tool(client: TestClient) -> None:
|
|
| 97 |
assert len(dates) > 5
|
| 98 |
assert dates == sorted(dates, reverse=True) # newest first
|
| 99 |
assert min(dates) >= (date.today() - timedelta(days=365)).isoformat()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
assert len(dates) > 5
|
| 98 |
assert dates == sorted(dates, reverse=True) # newest first
|
| 99 |
assert min(dates) >= (date.today() - timedelta(days=365)).isoformat()
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def test_list_recent_days_over_cap_is_an_error(client: TestClient) -> None:
|
| 103 |
+
resp = client.post(
|
| 104 |
+
"/lipsync/mcp",
|
| 105 |
+
json=rpc("tools/call", {"name": "list_recent", "arguments": {"days": 366}}),
|
| 106 |
+
headers=MCP_HEADERS,
|
| 107 |
+
)
|
| 108 |
+
assert resp.json()["result"]["isError"] is True
|
uv.lock
CHANGED
|
@@ -976,6 +976,7 @@ dependencies = [
|
|
| 976 |
{ name = "mcp" },
|
| 977 |
{ name = "rank-bm25" },
|
| 978 |
{ name = "sentence-transformers" },
|
|
|
|
| 979 |
{ name = "uvicorn" },
|
| 980 |
]
|
| 981 |
|
|
@@ -991,6 +992,7 @@ requires-dist = [
|
|
| 991 |
{ name = "mcp", specifier = ">=1.27,<2" },
|
| 992 |
{ name = "rank-bm25", specifier = ">=0.2.2" },
|
| 993 |
{ name = "sentence-transformers", specifier = ">=3.0" },
|
|
|
|
| 994 |
{ name = "uvicorn", specifier = ">=0.30" },
|
| 995 |
]
|
| 996 |
|
|
|
|
| 976 |
{ name = "mcp" },
|
| 977 |
{ name = "rank-bm25" },
|
| 978 |
{ name = "sentence-transformers" },
|
| 979 |
+
{ name = "starlette" },
|
| 980 |
{ name = "uvicorn" },
|
| 981 |
]
|
| 982 |
|
|
|
|
| 992 |
{ name = "mcp", specifier = ">=1.27,<2" },
|
| 993 |
{ name = "rank-bm25", specifier = ">=0.2.2" },
|
| 994 |
{ name = "sentence-transformers", specifier = ">=3.0" },
|
| 995 |
+
{ name = "starlette" },
|
| 996 |
{ name = "uvicorn", specifier = ">=0.30" },
|
| 997 |
]
|
| 998 |
|