-
Notifications
You must be signed in to change notification settings - Fork 767
feat: cascade StrEnum validation + chat-agent integration guide #273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Fearvox
wants to merge
4
commits into
EverMind-AI:main
Choose a base branch
from
Fearvox:proofstorm/r3-cascade-strenum-integration-guide
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
efd7188
feat(cascade): add StrEnum validation for md_change_state fields
Fearvox 45dcccd
docs: add chat-agent integration guide with search tool schema (#193)
Fearvox b8c31a5
fix(cascade): move enums to everos.core.enums to satisfy import-linter
Fearvox c721d07
fix: address codex GPT-5.5 brake findings (BLOCK→fixes)
Fearvox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,195 @@ | ||
| # Chat Agent Integration Guide | ||
|
|
||
| Recommended patterns for integrating a Chat Agent (LLM-based assistant) | ||
| with EverOS persistent memory. Covers the write path (ingesting | ||
| conversations), the read path (recalling memories on demand), and an | ||
| official tool schema for function-calling agents. | ||
|
|
||
| ## Architecture: On-Demand Search vs Per-Turn RAG | ||
|
|
||
| | Pattern | How it works | Trade-off | | ||
| |---|---|---| | ||
| | **Per-turn RAG** | Every turn, retrieve memories and inject into the LLM context window before generating a response. | Simple but pollutes context with irrelevant memories; burns tokens on every turn. | | ||
| | **On-demand search** | The agent decides *when* to recall by calling a memory search tool. | Token-efficient; closer to how human memory works (you don't recall everything every sentence). | | ||
|
|
||
| **Recommendation: on-demand search.** Keep short-term context (the last | ||
| *n* turns) in the LLM `messages` array as working memory. Long-term | ||
| memory is retrieved only when the agent determines it needs historical | ||
| context. | ||
|
|
||
| ## Write Path | ||
|
|
||
| Ingest every conversation turn automatically. Do not wait for the agent | ||
| to decide what to remember. | ||
|
|
||
| ``` | ||
| POST /api/v1/memory/add | ||
| { | ||
| "session_id": "chat-abc123", | ||
| "messages": [ | ||
| { | ||
| "sender_id": "user_42", | ||
| "role": "user", | ||
| "content": "I prefer dark mode for all my apps", | ||
| "timestamp": 1740564000000 | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| When you need to trigger memory extraction immediately (e.g. end of | ||
| conversation), call flush: | ||
|
|
||
| ``` | ||
| POST /api/v1/memory/flush | ||
| { | ||
| "session_id": "chat-abc123" | ||
| } | ||
| ``` | ||
|
|
||
| Extraction also fires automatically when the buffer reaches a size | ||
| threshold. Calling flush is optional but useful when you want memories | ||
| available for search right away. | ||
|
|
||
| See [POST /api/v1/memory/add](api.md#post-apiv1memoryadd) for the | ||
| full request schema. | ||
|
|
||
| ## Read Path | ||
|
|
||
| When the agent needs to recall past context, have it call the search | ||
| tool: | ||
|
|
||
| ``` | ||
| POST /api/v1/memory/search | ||
| { | ||
| "user_id": "user_42", | ||
| "query": "dark mode preferences", | ||
| "filters": { | ||
| "timestamp": { | ||
| "gte": 1740480000000, | ||
| "lt": 1740566400000 | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| See [POST /api/v1/memory/search](api.md#post-apiv1memorysearch) for | ||
| the full request schema. | ||
|
|
||
| ### Time-Range Filtering | ||
|
|
||
| For natural-language time references ("what we discussed yesterday about | ||
| X"), resolve the spoken time window to concrete `timestamp` bounds in | ||
| the `filters` field: | ||
|
|
||
| - Use Unix epoch milliseconds **or** ISO-8601 strings. | ||
| - `gte` / `lt` operators bracket the window. | ||
| - Timestamps reflect **when the conversation happened**, not when the | ||
| memory was extracted. If your extraction pipeline is async (flush- | ||
| based), propagate the original conversation timestamp. | ||
|
|
||
| ```json | ||
| { | ||
| "filters": { | ||
| "AND": [ | ||
| {"timestamp": {"gte": 1740480000000, "lt": 1740566400000}}, | ||
| {"session_id": {"eq": "chat-abc123"}} | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Retrieval Methods | ||
|
|
||
| | Method | When to use | | ||
| |---|---| | ||
| | `hybrid` (default) | General-purpose — combines BM25 + vector search. Best starting point. | | ||
| | `keyword` | When the query is exact-match friendly (e.g. function names, error codes). | | ||
| | `vector` | When semantic similarity matters more than keyword overlap. | | ||
| | `agentic` | When you want the system to run multi-step retrieval with LLM sufficiency checks. | | ||
|
|
||
| ## Official Tool Schema | ||
|
|
||
| The following OpenAI-compatible tool definition exposes memory search as | ||
| a function the agent can call. Fields align with the `/search` endpoint | ||
| documented in [api.md](api.md#post-apiv1memorysearch). | ||
|
|
||
| ```json | ||
| { | ||
| "type": "function", | ||
| "function": { | ||
| "name": "memory_search", | ||
| "description": "Search the user's long-term memory for relevant past conversations, facts, and context. Use when the user references previous sessions, asks about past decisions, or when historical context would improve your response.", | ||
| "parameters": { | ||
| "type": "object", | ||
| "properties": { | ||
| "query": { | ||
| "type": "string", | ||
| "description": "Search query — what to look for in past memories. Be specific." | ||
| }, | ||
| "user_id": { | ||
| "type": "string", | ||
| "description": "Memory owner (user). Set exactly one of user_id or agent_id." | ||
| }, | ||
| "agent_id": { | ||
| "type": "string", | ||
| "description": "Memory owner (agent). Set exactly one of user_id or agent_id." | ||
| }, | ||
| "top_k": { | ||
| "type": "integer", | ||
| "default": -1, | ||
| "description": "Maximum results. -1 uses server default." | ||
| }, | ||
| "filters": { | ||
| "type": "object", | ||
| "description": "Optional filters for time range, session, or other dimensions.", | ||
| "properties": { | ||
| "timestamp": { | ||
| "type": "object", | ||
| "description": "Time range filter. Use gte/lt with Unix epoch ms or ISO-8601 strings.", | ||
| "properties": { | ||
| "gte": {"type": ["integer", "string"], "description": "Start of time range (inclusive)"}, | ||
| "lt": {"type": ["integer", "string"], "description": "End of time range (exclusive)"} | ||
| } | ||
| }, | ||
| "session_id": { | ||
| "type": "object", | ||
| "properties": { | ||
| "eq": {"type": "string", "description": "Filter to a specific session"} | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "required": ["query"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| > **Note:** The `/search` endpoint requires exactly one of `user_id` or | ||
| > `agent_id`. Both are omitted from `required` above because JSON Schema | ||
| > does not support XOR constraints. The server returns 422 if neither or | ||
| > both are set. | ||
|
|
||
| ### MCP Tool Reference | ||
|
|
||
| For Claude Code and other MCP-compatible agents, a reference | ||
| implementation is available at | ||
| [`use-cases/claude-code-plugin/skills/memory-tools.md`](../use-cases/claude-code-plugin/skills/memory-tools.md). | ||
| That document describes the `evermem_search` tool and when to use it. | ||
|
|
||
| ## Key Integration Points | ||
|
|
||
| 1. **Write automatic, read agent-initiated.** Every turn goes through | ||
| `/add`; the agent calls `/search` only when it needs context. | ||
|
|
||
| 2. **Session scoping.** Use `session_id` to group turns from one | ||
| conversation. The `/search` endpoint can filter by session. | ||
|
|
||
| 3. **Owner scoping.** Pass `user_id` for user-facing agents or | ||
| `agent_id` for autonomous agents. Results never cross owner | ||
| boundaries. | ||
|
|
||
| 4. **App / project scoping.** Use `app_id` and `project_id` to | ||
| isolate memories across different products or environments. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| """Shared StrEnum types used across EverOS layers. | ||
|
|
||
| These enums live at the ``everos.core`` level so both ``infra`` and | ||
| ``memory`` can import them without violating the layered-architecture | ||
| contract enforced by import-linter. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from enum import StrEnum | ||
|
|
||
|
|
||
| class ChangeKind(StrEnum): | ||
| """Registered cascade handler kinds. | ||
|
|
||
| Each value corresponds to a :class:`Handler` subclass's ``kind`` | ||
| class attribute in :mod:`everos.memory.cascade.handlers`. | ||
| """ | ||
|
|
||
| EPISODE = "episode" | ||
| ATOMIC_FACT = "atomic_fact" | ||
| FORESIGHT = "foresight" | ||
| AGENT_CASE = "agent_case" | ||
| AGENT_SKILL = "agent_skill" | ||
| USER_PROFILE = "user_profile" | ||
|
|
||
|
|
||
| class ChangeType(StrEnum): | ||
| """Lifecycle hint for a single md path's work-queue row. | ||
|
|
||
| The handler re-derives truth from the actual file state at run | ||
| time (DD-3 in 12 doc); this field is a dispatch hint only. | ||
| """ | ||
|
|
||
| ADDED = "added" | ||
| MODIFIED = "modified" | ||
| DELETED = "deleted" | ||
|
|
||
|
|
||
| class ChangeStatus(StrEnum): | ||
| """Work-queue row lifecycle. | ||
|
|
||
| ``PROCESSING`` is an internal claim state used by | ||
| :meth:`MdChangeStateRepo.claim_one`; CLI output rolls it back | ||
| into ``PENDING`` for display (16 doc §4.2 — DD-12). | ||
| """ | ||
|
|
||
| PENDING = "pending" | ||
| PROCESSING = "processing" | ||
| DONE = "done" | ||
| FAILED = "failed" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/everos/core/enums.py 这里的 Enum 命名太短了,按我的理解,如果提取到公用的 core 级别,命名需要有区分度,从 core 看代码可以直接知道是用在什么地方。可以适当参考 领域命名+字段命名结合。
这里 ChangeKind 太通用了,MemoryCascadeChangeKind 会直观很多。
@Fearvox
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是的 应该再细分一下taxonomy Thx