This commit is contained in:
Ziyang Guo 2026-09-25 11:05:12 +08:00 • committed by GitHub
commit 2f606fd95b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 47 additions and 1 deletions

View file

@ -4,6 +4,24 @@ from ..base_step import BaseStep
from ...components import R
def _render_reindex(details: dict) -> str:
"""Render the store's reindex report as one readable summary line.
ReMe Studio's settings panel shows ``response.answer`` when it is a string
and otherwise falls back to a generic "index rebuilt" message
(``reme_studio/app/settings-center.tsx``). Returning the report dict as the
answer left that branch unreachable, so the operator never learned what was
actually rebuilt. The report itself stays in ``metadata`` for programmatic
consumers.
"""
scope = str(details.get("scope") or "all")
per_scope = {name: entry for name, entry in details.items() if isinstance(entry, dict)}
if per_scope:
counts = ", ".join(f"{name}={entry.get('indexed', 0)}" for name, entry in per_scope.items())
return f"Reindexed scope={scope}: {counts}"
return f"Reindexed scope={scope}: {details.get('indexed', 0)} indexed"
@R.register("reindex_step")
class ReindexStep(BaseStep):
"""Rebuild BM25, embeddings, and/or tags without scanning workspace files."""
@ -13,7 +31,7 @@ class ReindexStep(BaseStep):
scope = str(self.context.get("scope", "all"))
details = await self.file_store.reindex(scope)
self.context.response.answer = details
self.context.response.answer = _render_reindex(details)
self.context.response.metadata.update(details)
self.context.response.metadata["scope"] = scope
return self.context.response

View file

@ -23,6 +23,7 @@ async def test_reindex_step_delegates_scope(scope):
store.reindex.assert_awaited_once_with(scope)
store.clear.assert_not_called()
assert response.metadata == {"indexed": 3, "scope": scope}
assert response.answer == f"Reindexed scope={scope}: 3 indexed"
@pytest.mark.asyncio
@ -41,6 +42,33 @@ async def test_reindex_step_delegates_all_once():
store.reindex.assert_awaited_once_with("all")
assert response.metadata == details
assert response.answer == "Reindexed scope=all: bm25=3, embedding=3, tag=3"
@pytest.mark.asyncio
async def test_reindex_answer_is_a_readable_summary_of_the_report():
"""The answer is a string, so Studio shows it instead of a generic message.
ReMe Studio only displays ``response.answer`` when it is a string
(``reme_studio/app/settings-center.tsx``); a dict answer silently fell back
to the generic "index rebuilt" text and the operator never saw the counts.
The full report stays in metadata either way.
"""
store = LocalFileStore(name="test_reindex_answer", embedding_store="")
store.reindex = AsyncMock(
return_value={
"scope": "all",
"bm25": {"scope": "bm25", "indexed": 7},
"embedding": {"scope": "embedding", "indexed": 5},
"tag": {"scope": "tag", "indexed": 2},
},
)
response = await ReindexStep(file_store=store)(RuntimeContext(scope="all"))
assert isinstance(response.answer, str)
assert response.answer == "Reindexed scope=all: bm25=7, embedding=5, tag=2"
assert response.metadata["bm25"] == {"scope": "bm25", "indexed": 7}
def test_reindex_job_schema_exposes_tag_scope():