Skip to content

Commit ed38546

Browse files
Wang-Daojiyuan.wang
andauthored
Feat/merge api refactor to dev (#531)
* new type * llm reconstruct and add search api modify * llm construction * add delete and get, modify chat * modify code * modify code * modify code * coding chat * fix bug in get and delete * add internet reference in playground chat stream * remove moscube * modify code * fix pre_commit * fix make test * finish info transfer * add info and custom tags * modify model product fileds * fix get api bug * fix bug --------- Co-authored-by: yuan.wang <[email protected]>
1 parent 9341861 commit ed38546

File tree

13 files changed

+213
-45
lines changed

13 files changed

+213
-45
lines changed

src/memos/api/handlers/add_handler.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
from memos.api.handlers.base_handler import BaseHandler, HandlerDependencies
99
from memos.api.product_models import APIADDRequest, MemoryResponse
10+
from memos.memories.textual.item import (
11+
list_all_fields,
12+
)
1013
from memos.multi_mem_cube.composite_cube import CompositeCubeView
1114
from memos.multi_mem_cube.single_cube import SingleCubeView
1215
from memos.multi_mem_cube.views import MemCubeView
@@ -44,6 +47,13 @@ def handle_add_memories(self, add_req: APIADDRequest) -> MemoryResponse:
4447
"""
4548
self.logger.info(f"[AddHandler] Add Req is: {add_req}")
4649

50+
if add_req.info:
51+
exclude_fields = list_all_fields()
52+
info_len = len(add_req.info)
53+
add_req.info = {k: v for k, v in add_req.info.items() if k not in exclude_fields}
54+
if len(add_req.info) < info_len:
55+
self.logger.warning(f"[AddHandler] info fields can not contain {exclude_fields}.")
56+
4757
cube_view = self._build_cube_view(add_req)
4858

4959
results = cube_view.add_memories(add_req)

src/memos/api/handlers/memory_handler.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
This module handles retrieving all memories or specific subgraphs based on queries.
55
"""
66

7-
from typing import Any, Literal
7+
from typing import TYPE_CHECKING, Any, Literal
88

99
from memos.api.handlers.formatters_handler import format_memory_item
1010
from memos.api.product_models import (
@@ -24,6 +24,10 @@
2424
)
2525

2626

27+
if TYPE_CHECKING:
28+
from memos.memories.textual.preference import TextualMemoryItem
29+
30+
2731
logger = get_logger(__name__)
2832

2933

@@ -161,17 +165,20 @@ def handle_get_subgraph(
161165
def handle_get_memories(get_mem_req: GetMemoryRequest, naive_mem_cube: Any) -> GetMemoryResponse:
162166
# TODO: Implement get memory with filter
163167
memories = naive_mem_cube.text_mem.get_all(user_name=get_mem_req.mem_cube_id)["nodes"]
164-
filter_params: dict[str, Any] = {}
165-
if get_mem_req.user_id is not None:
166-
filter_params["user_id"] = get_mem_req.user_id
167-
if get_mem_req.mem_cube_id is not None:
168-
filter_params["mem_cube_id"] = get_mem_req.mem_cube_id
169-
preferences = naive_mem_cube.pref_mem.get_memory_by_filter(filter_params)
168+
preferences: list[TextualMemoryItem] = []
169+
if get_mem_req.include_preference:
170+
filter_params: dict[str, Any] = {}
171+
if get_mem_req.user_id is not None:
172+
filter_params["user_id"] = get_mem_req.user_id
173+
if get_mem_req.mem_cube_id is not None:
174+
filter_params["mem_cube_id"] = get_mem_req.mem_cube_id
175+
preferences = naive_mem_cube.pref_mem.get_memory_by_filter(filter_params)
176+
preferences = [format_memory_item(mem) for mem in preferences]
170177
return GetMemoryResponse(
171178
message="Memories retrieved successfully",
172179
data={
173180
"text_mem": memories,
174-
"pref_mem": [format_memory_item(mem) for mem in preferences],
181+
"pref_mem": preferences,
175182
},
176183
)
177184

src/memos/api/product_models.py

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
# Import message types from core types module
88
from memos.log import get_logger
9-
from memos.types import MessageDict, MessagesType, PermissionDict, SearchMode
9+
from memos.types import MessageList, MessagesType, PermissionDict, SearchMode
1010

1111

1212
logger = get_logger(__name__)
@@ -72,40 +72,57 @@ class ChatRequest(BaseRequest):
7272

7373
user_id: str = Field(..., description="User ID")
7474
query: str = Field(..., description="Chat query message")
75-
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
7675
readable_cube_ids: list[str] | None = Field(
7776
None, description="List of cube IDs user can read for multi-cube chat"
7877
)
7978
writable_cube_ids: list[str] | None = Field(
8079
None, description="List of cube IDs user can write for multi-cube chat"
8180
)
82-
history: list[MessageDict] | None = Field(None, description="Chat history")
81+
history: MessageList | None = Field(None, description="Chat history")
8382
mode: SearchMode = Field(SearchMode.FAST, description="search mode: fast, fine, or mixture")
84-
internet_search: bool = Field(True, description="Whether to use internet search")
8583
system_prompt: str | None = Field(None, description="Base system prompt to use for chat")
8684
top_k: int = Field(10, description="Number of results to return")
87-
threshold: float = Field(0.5, description="Threshold for filtering references")
8885
session_id: str | None = Field(None, description="Session ID for soft-filtering memories")
8986
include_preference: bool = Field(True, description="Whether to handle preference memory")
9087
pref_top_k: int = Field(6, description="Number of preference results to return")
91-
filter: dict[str, Any] | None = Field(None, description="Filter for the memory")
9288
model_name_or_path: str | None = Field(None, description="Model name to use for chat")
9389
max_tokens: int | None = Field(None, description="Max tokens to generate")
9490
temperature: float | None = Field(None, description="Temperature for sampling")
9591
top_p: float | None = Field(None, description="Top-p (nucleus) sampling parameter")
9692
add_message_on_answer: bool = Field(True, description="Add dialogs to memory after chat")
93+
94+
# ==== Filter conditions ====
95+
filter: dict[str, Any] | None = Field(
96+
None,
97+
description="""
98+
Filter for the memory, example:
99+
{
100+
"`and` or `or`": [
101+
{"id": "uuid-xxx"},
102+
{"created_at": {"gt": "2024-01-01"}},
103+
]
104+
}
105+
""",
106+
)
107+
108+
# ==== Extended capabilities ====
109+
internet_search: bool = Field(True, description="Whether to use internet search")
110+
threshold: float = Field(0.5, description="Threshold for filtering references")
111+
112+
# ==== Backward compatibility ====
113+
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
97114
moscube: bool = Field(
98115
False, description="(Deprecated) Whether to use legacy MemOSCube pipeline"
99116
)
100117

101118

102119
class ChatCompleteRequest(BaseRequest):
103-
"""Request model for chat operations."""
120+
"""Request model for chat operations. will (Deprecated), instead use APIChatCompleteRequest."""
104121

105122
user_id: str = Field(..., description="User ID")
106123
query: str = Field(..., description="Chat query message")
107124
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
108-
history: list[MessageDict] | None = Field(None, description="Chat history")
125+
history: MessageList | None = Field(None, description="Chat history")
109126
internet_search: bool = Field(False, description="Whether to use internet search")
110127
system_prompt: str | None = Field(None, description="Base prompt to use for chat")
111128
top_k: int = Field(10, description="Number of results to return")
@@ -191,7 +208,7 @@ class MemoryCreateRequest(BaseRequest):
191208
"""Request model for creating memories."""
192209

193210
user_id: str = Field(..., description="User ID")
194-
messages: list[MessageDict] | None = Field(None, description="List of messages to store.")
211+
messages: MessagesType | None = Field(None, description="List of messages to store.")
195212
memory_content: str | None = Field(None, description="Memory content to store")
196213
doc_path: str | None = Field(None, description="Path to document to store")
197214
mem_cube_id: str | None = Field(None, description="Cube ID")
@@ -269,7 +286,15 @@ class APISearchRequest(BaseRequest):
269286
# TODO: maybe add detailed description later
270287
filter: dict[str, Any] | None = Field(
271288
None,
272-
description=("Filter for the memory"),
289+
description="""
290+
Filter for the memory, example:
291+
{
292+
"`and` or `or`": [
293+
{"id": "uuid-xxx"},
294+
{"created_at": {"gt": "2024-01-01"}},
295+
]
296+
}
297+
""",
273298
)
274299

275300
# ==== Extended capabilities ====
@@ -291,7 +316,7 @@ class APISearchRequest(BaseRequest):
291316
)
292317

293318
# ==== Context ====
294-
chat_history: MessagesType | None = Field(
319+
chat_history: MessageList | None = Field(
295320
None,
296321
description=(
297322
"Historical chat messages used internally by algorithms. "
@@ -421,7 +446,7 @@ class APIADDRequest(BaseRequest):
421446
)
422447

423448
# ==== Chat history ====
424-
chat_history: MessagesType | None = Field(
449+
chat_history: MessageList | None = Field(
425450
None,
426451
description=(
427452
"Historical chat messages used internally by algorithms. "
@@ -540,31 +565,49 @@ class APIChatCompleteRequest(BaseRequest):
540565

541566
user_id: str = Field(..., description="User ID")
542567
query: str = Field(..., description="Chat query message")
543-
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
544568
readable_cube_ids: list[str] | None = Field(
545569
None, description="List of cube IDs user can read for multi-cube chat"
546570
)
547571
writable_cube_ids: list[str] | None = Field(
548572
None, description="List of cube IDs user can write for multi-cube chat"
549573
)
550-
history: list[MessageDict] | None = Field(None, description="Chat history")
551-
internet_search: bool = Field(False, description="Whether to use internet search")
552-
system_prompt: str | None = Field(None, description="Base system prompt to use for chat")
574+
history: MessageList | None = Field(None, description="Chat history")
553575
mode: SearchMode = Field(SearchMode.FAST, description="search mode: fast, fine, or mixture")
576+
system_prompt: str | None = Field(None, description="Base system prompt to use for chat")
554577
top_k: int = Field(10, description="Number of results to return")
555-
threshold: float = Field(0.5, description="Threshold for filtering references")
556-
session_id: str | None = Field(
557-
"default_session", description="Session ID for soft-filtering memories"
558-
)
578+
session_id: str | None = Field(None, description="Session ID for soft-filtering memories")
559579
include_preference: bool = Field(True, description="Whether to handle preference memory")
560580
pref_top_k: int = Field(6, description="Number of preference results to return")
561-
filter: dict[str, Any] | None = Field(None, description="Filter for the memory")
562581
model_name_or_path: str | None = Field(None, description="Model name to use for chat")
563582
max_tokens: int | None = Field(None, description="Max tokens to generate")
564583
temperature: float | None = Field(None, description="Temperature for sampling")
565584
top_p: float | None = Field(None, description="Top-p (nucleus) sampling parameter")
566585
add_message_on_answer: bool = Field(True, description="Add dialogs to memory after chat")
567586

587+
# ==== Filter conditions ====
588+
filter: dict[str, Any] | None = Field(
589+
None,
590+
description="""
591+
Filter for the memory, example:
592+
{
593+
"`and` or `or`": [
594+
{"id": "uuid-xxx"},
595+
{"created_at": {"gt": "2024-01-01"}},
596+
]
597+
}
598+
""",
599+
)
600+
601+
# ==== Extended capabilities ====
602+
internet_search: bool = Field(True, description="Whether to use internet search")
603+
threshold: float = Field(0.5, description="Threshold for filtering references")
604+
605+
# ==== Backward compatibility ====
606+
mem_cube_id: str | None = Field(None, description="Cube ID to use for chat")
607+
moscube: bool = Field(
608+
False, description="(Deprecated) Whether to use legacy MemOSCube pipeline"
609+
)
610+
568611

569612
class AddStatusRequest(BaseRequest):
570613
"""Request model for checking add status."""
@@ -594,7 +637,7 @@ class SuggestionRequest(BaseRequest):
594637
user_id: str = Field(..., description="User ID")
595638
mem_cube_id: str = Field(..., description="Cube ID")
596639
language: Literal["zh", "en"] = Field("zh", description="Language for suggestions")
597-
message: list[MessageDict] | None = Field(None, description="List of messages to store.")
640+
message: MessagesType | None = Field(None, description="List of messages to store.")
598641

599642

600643
# ─── MemOS Client Response Models ──────────────────────────────────────────────

0 commit comments

Comments
 (0)