Skip to content

Say when a saved memory becomes searchable - #3

Merged
dani1005 merged 3 commits into
EverMind-AI:mainfrom
gloryfromca:docs/searchable-wording
Oct 12, 2026
Merged

dani1005 merged 3 commits into
EverMind-AI:mainfrom
gloryfromca:docs/searchable-wording

Conversation

@gloryfromca

Copy link
Copy Markdown
Member

Summary

add_memory(wait=true) replied "Stored and extracted; the memory is now searchable." Extraction finishing and the memory becoming searchable are two steps, and on a self-hosted EverOS the index catches up about half a second after the write. Verified on 2026-10-10 against a local everos server start (everos 1.4.1): a search_memory call issued right after that reply returned nothing; the same query a second later found the memory, and the server log shows the cascade indexing the new episode ~0.5 s after /memory/flush returned.

This changes only wording:

  • the wait=true reply now says the memory is searchable once the index catches up, usually within a second;
  • the add_memory docstring says the same for the wait=true branch;
  • README: the tool table no longer says wait=true blocks "until it is searchable", and Good to know gains a bullet about the two steps and list_memories showing new entries sooner.

Tests assert on the stable prefix Stored and extracted instead of now searchable.

Verification

uv sync --dev --locked
uv run ruff check .      # OK
uv run pytest -q         # all tests pass

🤖 Generated with Claude Code

`add_memory(wait=true)` replied "the memory is now searchable", but
extraction finishing and the search index catching up are two steps.
Against a self-hosted EverOS the index lagged the write by about half a
second: a search_memory call issued right after the reply found nothing
and the same query a second later found the memory. Say so in the reply,
the docstring and the README instead of promising immediate hits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@dani1005 dani1005 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracking this down. The measurement is convincing: wait=true currently claims more than it delivers, and making the wording honest is the right first step.

The catch is that rewording alone leaves the tool contract self-contradictory (see inline). The docstring still tells the model to use wait=true when it must search right away, which is exactly the case this PR shows still fails.

Suggested direction. Make wait=true actually wait for searchability. In Conversation.store, after the flush, poll briefly until the new entry is visible, or use a server-side option that waits for indexing if the API has one. Then "now searchable" is true again and the docs need no hedging. If you'd rather land the wording first, please at least:

  1. Drop "only when you must search for it right away" from the add_memory docstring.
  2. Use one latency statement everywhere. search_memory's docstring and its empty-result note say "saved in the last minute may not be indexed yet"; this PR says "usually within a second"; the background path says "a few seconds later" / "shortly".
  3. Update Conversation.store's docstring (conversation.py:111), which still says "extracted" means searchable.

Then follow up with the real fix in a separate PR.

Note: EverMind-AI/EverOS#484 repeats the "about a second" claim in docs/mcp.md, so it's worth landing the two consistently.

Comment thread src/everos_mcp/server.py Outdated
the memory is searchable a few seconds later, and a failure is reported
on a later tool result. Set wait=true only when you must search for it
right away — it blocks until extraction finishes.
right away — it blocks until extraction finishes; the index catches up

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence still tells the model to use wait=true when it must search right away, but the PR's own finding is that wait=true doesn't make the memory searchable right away. A model that follows the docstring calls search_memory immediately, lands inside the index lag, gets "No relevant memories found", and may tell the user the save failed. Either make wait=true wait for indexing (preferred), or drop "only when you must search for it right away".

Comment thread src/everos_mcp/server.py Outdated
if status == "extracted":
return conv.reply("Stored and extracted; the memory is now searchable.")
return conv.reply(
"Stored and extracted; searchable once the index catches up, usually within a second."

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things on this line:

  • Latency figure. "usually within a second" comes from one self-hosted measurement. Meanwhile search_memory (docstring and empty-result note) says memories from "the last minute" may not be indexed yet. On Cloud or a loaded server the model may trust "a second", retry once, and give up. Please pick one conservative statement and use it everywhere.
  • Line length. This line is 102 characters, over line-length = 100 in pyproject.toml. CI doesn't catch it because E501 isn't enabled. Splitting it into two adjacent literals, like the reply just below, fixes it.

Comment thread tests/test_everos_mcp.py
)
reply = run(server.add_memory(user_message="x", wait=True))
assert "now searchable" in reply
assert "Stored and extracted" in reply

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With only the stable prefix asserted, nothing guards the wording this PR fixes. If "now searchable" comes back later, all three updated assertions still pass. Maybe add assert "now searchable" not in reply here (and at 750 / 841).

Review on EverMind-AI#3: the docstring still told the model to use wait=true when
it must search right away, and the reply promised "within a second"
from a single measurement while search_memory says "the last minute".
Making wait=true block until the index has caught up was considered
and rejected: how long indexing takes depends on server load, so any
bound would be a guess. Instead every place now says the same thing:
memories saved in the last minute may not be indexed yet, and
list_memories shows them sooner. Tests also assert the old "now
searchable" wording is gone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gloryfromca

Copy link
Copy Markdown
Member Author

Thanks for the careful read. Pushed a follow-up commit:

  • Docstring: dropped "only when you must search for it right away". wait=true is now described as "block until extraction has finished", and the docstring carries the same statement as search_memory: memories saved in the last minute may not be indexed yet; list_memories shows them sooner.
  • Reply: the wait=true reply uses that same sentence instead of "usually within a second"; the README bullet too, so the three places agree. Also fixed the 102-char line.
  • Tests: the three assertions now also check "now searchable" not in reply.

On making wait=true wait for indexing: we decided against it. How long the index takes to catch up depends on server load (and on Cloud vs self-hosted), so any bound we picked would be a guess, and a bounded wait that times out would need yet another message. One honest statement everywhere seemed better than a sometimes-true guarantee.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dani1005

Copy link
Copy Markdown
Member

Thanks, this all looks good, and the reasoning on not waiting for the index makes sense to me. I pushed one small follow-up (9677d0d): the Conversation.store docstring still said "extracted" means searchable, which is the claim this PR retires.

@dani1005 dani1005 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@dani1005
dani1005 merged commit dfa3cc3 into EverMind-AI:main Oct 12, 2026
2 checks passed
@dani1005 dani1005 mentioned this pull request Oct 15, 2026
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.

2 participants