Skip to content

Commit f0c528c

Browse files
authored
♻️ Improvement: Warn the user trying to proceed when embedding model is not set
2 parents 6bc3373 + fbe1e98 commit f0c528c

File tree

16 files changed

+776
-265
lines changed

16 files changed

+776
-265
lines changed

backend/services/config_sync_service.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,6 @@
2626
logger = logging.getLogger("config_sync_service")
2727

2828

29-
def _parse_optional_int(value) -> Optional[int]:
30-
try:
31-
return int(value)
32-
except (ValueError, TypeError):
33-
return None
34-
35-
3629
def handle_model_config(tenant_id: str, user_id: str, config_key: str, model_id: Optional[int], tenant_config_dict: dict) -> None:
3730
"""
3831
Handle model configuration updates, deletions, and settings operations
@@ -56,7 +49,8 @@ def handle_model_config(tenant_id: str, user_id: str, config_key: str, model_id:
5649
user_id, tenant_id, config_key, model_id)
5750
return
5851

59-
current_model_id = _parse_optional_int(tenant_config_dict.get(config_key))
52+
current_model_id = tenant_config_dict.get(config_key)
53+
current_model_id = int(current_model_id) if str(current_model_id).isdigit() else None
6054

6155
if current_model_id == model_id:
6256
tenant_config_manager.update_single_config(tenant_id, config_key)

backend/services/memory_config_service.py

Lines changed: 124 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
from typing import Dict, List, Union
33

44
from consts.const import (
5-
MEMORY_SWITCH_KEY,
6-
MEMORY_AGENT_SHARE_KEY,
7-
DISABLE_AGENT_ID_KEY,
8-
DISABLE_USERAGENT_ID_KEY,
9-
DEFAULT_MEMORY_SWITCH_KEY,
10-
DEFAULT_MEMORY_AGENT_SHARE_KEY,
5+
MEMORY_SWITCH_KEY,
6+
MEMORY_AGENT_SHARE_KEY,
7+
DISABLE_AGENT_ID_KEY,
8+
DISABLE_USERAGENT_ID_KEY,
9+
DEFAULT_MEMORY_SWITCH_KEY,
10+
DEFAULT_MEMORY_AGENT_SHARE_KEY,
1111
)
1212
from consts.model import MemoryAgentShareMode
1313
from database.memory_config_db import (
14-
get_all_configs_by_user_id,
15-
get_memory_config_info,
16-
insert_config,
17-
delete_config_by_config_id,
18-
update_config_by_id,
14+
get_all_configs_by_user_id,
15+
get_memory_config_info,
16+
insert_config,
17+
delete_config_by_config_id,
18+
update_config_by_id,
1919
)
2020
from nexent.core.agents.agent_model import MemoryContext, MemoryUserConfig
2121
from utils.memory_utils import build_memory_config
@@ -31,15 +31,15 @@
3131
# ---------------------------------------------------------------------------
3232

3333
def _aggregate_records(records: List[Dict[str, Union[str, int]]]) -> Dict[str, Union[str, List[str]]]:
34-
"""Aggregate DB rows -> {config_key: value_or_list}"""
35-
aggregated: Dict[str, Union[str, List[str]]] = {}
36-
for r in records:
37-
key = r["config_key"]
38-
if r.get("value_type") == _MULTI_TYPE:
39-
aggregated.setdefault(key, []).append(r["config_value"])
40-
else:
41-
aggregated[key] = r["config_value"]
42-
return aggregated
34+
"""Aggregate DB rows -> {config_key: value_or_list}"""
35+
aggregated: Dict[str, Union[str, List[str]]] = {}
36+
for r in records:
37+
key = r["config_key"]
38+
if r.get("value_type") == _MULTI_TYPE:
39+
aggregated.setdefault(key, []).append(r["config_value"])
40+
else:
41+
aggregated[key] = r["config_value"]
42+
return aggregated
4343

4444

4545
# ---------------------------------------------------------------------------
@@ -64,154 +64,154 @@ def get_user_configs(user_id: str) -> Dict[str, Union[str, List[str]]]:
6464

6565

6666
def _update_single_config(user_id: str, config_key: str, config_value: str) -> bool:
67-
"""Create or update a single-type configuration entry."""
68-
record_list = get_memory_config_info(user_id, config_key)
69-
70-
if not record_list:
71-
# Insert new record
72-
result = insert_config({
73-
"user_id": user_id,
74-
"config_key": config_key,
75-
"config_value": config_value,
76-
"value_type": _SINGLE_TYPE,
77-
"created_by": user_id,
78-
"updated_by": user_id,
79-
})
80-
if not result:
81-
logger.error(
82-
f"insert_config failed, user_id={user_id}, key={config_key}, value={config_value}"
83-
)
84-
return False
85-
else:
86-
# Update first record (there should be max one for single type)
87-
config_id = record_list[0]["config_id"]
88-
result = update_config_by_id(config_id, {
89-
"config_value": config_value,
90-
"updated_by": user_id,
91-
})
92-
if not result:
93-
logger.error(
94-
f"update_config_by_id failed, user_id={user_id}, key={config_key}, value={config_value}"
95-
)
96-
return False
97-
return True
67+
"""Create or update a single-type configuration entry."""
68+
record_list = get_memory_config_info(user_id, config_key)
69+
70+
if not record_list:
71+
# Insert new record
72+
result = insert_config({
73+
"user_id": user_id,
74+
"config_key": config_key,
75+
"config_value": config_value,
76+
"value_type": _SINGLE_TYPE,
77+
"created_by": user_id,
78+
"updated_by": user_id,
79+
})
80+
if not result:
81+
logger.error(
82+
f"insert_config failed, user_id={user_id}, key={config_key}, value={config_value}"
83+
)
84+
return False
85+
else:
86+
# Update first record (there should be max one for single type)
87+
config_id = record_list[0]["config_id"]
88+
result = update_config_by_id(config_id, {
89+
"config_value": config_value,
90+
"updated_by": user_id,
91+
})
92+
if not result:
93+
logger.error(
94+
f"update_config_by_id failed, user_id={user_id}, key={config_key}, value={config_value}"
95+
)
96+
return False
97+
return True
9898

9999

100100
def _add_multi_value(user_id: str, config_key: str, value: str) -> bool:
101-
"""Add a value to a multi-type list if it does not exist."""
102-
record_list = get_memory_config_info(user_id, config_key)
103-
if any(r["config_value"] == value for r in record_list):
104-
# Already exists, nothing to do
105-
return True
106-
107-
ok = insert_config({
108-
"user_id": user_id,
109-
"config_key": config_key,
110-
"config_value": value,
111-
"value_type": _MULTI_TYPE,
112-
"created_by": user_id,
113-
"updated_by": user_id,
114-
})
115-
if not ok:
116-
logger.error(
117-
f"insert_config failed, user_id={user_id}, key={config_key}, value={value}"
118-
)
119-
return ok
101+
"""Add a value to a multi-type list if it does not exist."""
102+
record_list = get_memory_config_info(user_id, config_key)
103+
if any(r["config_value"] == value for r in record_list):
104+
# Already exists, nothing to do
105+
return True
106+
107+
ok = insert_config({
108+
"user_id": user_id,
109+
"config_key": config_key,
110+
"config_value": value,
111+
"value_type": _MULTI_TYPE,
112+
"created_by": user_id,
113+
"updated_by": user_id,
114+
})
115+
if not ok:
116+
logger.error(
117+
f"insert_config failed, user_id={user_id}, key={config_key}, value={value}"
118+
)
119+
return ok
120120

121121

122122
def _remove_multi_value(user_id: str, config_key: str, value: str) -> bool:
123-
"""Soft-delete a specific value from a multi-type configuration list."""
124-
record_list = get_memory_config_info(user_id, config_key)
125-
for r in record_list:
126-
if r["config_value"] == value:
127-
ok = delete_config_by_config_id(r["config_id"], updated_by=user_id)
128-
if not ok:
129-
logger.error(
130-
f"delete_config_by_config_id failed, user_id={user_id}, key={config_key}, value={value}"
131-
)
132-
return ok
133-
# Value not found → treat as success
134-
return True
123+
"""Soft-delete a specific value from a multi-type configuration list."""
124+
record_list = get_memory_config_info(user_id, config_key)
125+
for r in record_list:
126+
if r["config_value"] == value:
127+
ok = delete_config_by_config_id(r["config_id"], updated_by=user_id)
128+
if not ok:
129+
logger.error(
130+
f"delete_config_by_config_id failed, user_id={user_id}, key={config_key}, value={value}"
131+
)
132+
return ok
133+
# Value not found → treat as success
134+
return True
135135

136136

137137
# ---------------------------------------------------------------------------
138138
# Public service helpers used by API layer
139139
# ---------------------------------------------------------------------------
140140

141141
def get_memory_switch(user_id: str) -> bool:
142-
configs = get_user_configs(user_id)
143-
return configs.get(MEMORY_SWITCH_KEY, "N") == "Y"
142+
configs = get_user_configs(user_id)
143+
return configs.get(MEMORY_SWITCH_KEY, "N") == "Y"
144144

145145

146146
def set_memory_switch(user_id: str, enabled: bool) -> bool:
147-
return _update_single_config(user_id, MEMORY_SWITCH_KEY, "Y" if enabled else "N")
147+
return _update_single_config(user_id, MEMORY_SWITCH_KEY, "Y" if enabled else "N")
148148

149149

150150
# Agent share (single string among always/ask/never)
151151
def get_agent_share(user_id: str) -> MemoryAgentShareMode:
152-
configs = get_user_configs(user_id)
153-
mode_str = configs.get(MEMORY_AGENT_SHARE_KEY, MemoryAgentShareMode.NEVER.value)
154-
try:
155-
return MemoryAgentShareMode(mode_str)
156-
except ValueError:
157-
# Unexpected value, default to NEVER
158-
return MemoryAgentShareMode.NEVER
152+
configs = get_user_configs(user_id)
153+
mode_str = configs.get(MEMORY_AGENT_SHARE_KEY, MemoryAgentShareMode.NEVER.value)
154+
try:
155+
return MemoryAgentShareMode(mode_str)
156+
except ValueError:
157+
# Unexpected value, default to NEVER
158+
return MemoryAgentShareMode.NEVER
159159

160160

161161
def set_agent_share(user_id: str, mode: MemoryAgentShareMode) -> bool:
162-
return _update_single_config(user_id, MEMORY_AGENT_SHARE_KEY, mode.value)
162+
return _update_single_config(user_id, MEMORY_AGENT_SHARE_KEY, mode.value)
163163

164164

165165
# Disable agent id list (multi)
166166
def get_disabled_agent_ids(user_id: str) -> List[str]:
167-
configs = get_user_configs(user_id)
168-
return configs.get(DISABLE_AGENT_ID_KEY, []) # type: ignore[return-value]
167+
configs = get_user_configs(user_id)
168+
return configs.get(DISABLE_AGENT_ID_KEY, []) # type: ignore[return-value]
169169

170170

171171
def add_disabled_agent_id(user_id: str, agent_id: str) -> bool:
172-
return _add_multi_value(user_id, DISABLE_AGENT_ID_KEY, agent_id)
172+
return _add_multi_value(user_id, DISABLE_AGENT_ID_KEY, agent_id)
173173

174174

175175
def remove_disabled_agent_id(user_id: str, agent_id: str) -> bool:
176-
return _remove_multi_value(user_id, DISABLE_AGENT_ID_KEY, agent_id)
176+
return _remove_multi_value(user_id, DISABLE_AGENT_ID_KEY, agent_id)
177177

178178

179179
# Disable user-agent id list (multi)
180180

181181
def get_disabled_useragent_ids(user_id: str) -> List[str]:
182-
configs = get_user_configs(user_id)
183-
return configs.get(DISABLE_USERAGENT_ID_KEY, []) # type: ignore[return-value]
182+
configs = get_user_configs(user_id)
183+
return configs.get(DISABLE_USERAGENT_ID_KEY, []) # type: ignore[return-value]
184184

185185

186186
def add_disabled_useragent_id(user_id: str, ua_id: str) -> bool:
187-
return _add_multi_value(user_id, DISABLE_USERAGENT_ID_KEY, ua_id)
187+
return _add_multi_value(user_id, DISABLE_USERAGENT_ID_KEY, ua_id)
188188

189189

190190
def remove_disabled_useragent_id(user_id: str, ua_id: str) -> bool:
191-
return _remove_multi_value(user_id, DISABLE_USERAGENT_ID_KEY, ua_id)
191+
return _remove_multi_value(user_id, DISABLE_USERAGENT_ID_KEY, ua_id)
192192

193193

194194
def build_memory_context(user_id: str, tenant_id: str, agent_id: str | int) -> MemoryContext:
195-
memory_user_config = MemoryUserConfig(
196-
memory_switch=get_memory_switch(user_id),
197-
agent_share_option=get_agent_share(user_id).value,
198-
disable_agent_ids=get_disabled_agent_ids(user_id),
199-
disable_user_agent_ids=get_disabled_useragent_ids(user_id),
200-
)
201-
# If user turn off the memory function, return minimum context directly
202-
if not memory_user_config.memory_switch:
203-
return MemoryContext(
204-
user_config=memory_user_config,
205-
memory_config=dict(),
206-
tenant_id=tenant_id,
207-
user_id=user_id,
208-
agent_id=str(agent_id),
209-
)
210-
211-
return MemoryContext(
212-
user_config=memory_user_config,
213-
memory_config=build_memory_config(tenant_id),
214-
tenant_id=tenant_id,
215-
user_id=user_id,
216-
agent_id=str(agent_id),
217-
)
195+
memory_user_config = MemoryUserConfig(
196+
memory_switch=get_memory_switch(user_id),
197+
agent_share_option=get_agent_share(user_id).value,
198+
disable_agent_ids=get_disabled_agent_ids(user_id),
199+
disable_user_agent_ids=get_disabled_useragent_ids(user_id),
200+
)
201+
# If user turn off the memory function, return minimum context directly
202+
if not memory_user_config.memory_switch:
203+
return MemoryContext(
204+
user_config=memory_user_config,
205+
memory_config=dict(),
206+
tenant_id=tenant_id,
207+
user_id=user_id,
208+
agent_id=str(agent_id),
209+
)
210+
211+
return MemoryContext(
212+
user_config=memory_user_config,
213+
memory_config=build_memory_config(tenant_id),
214+
tenant_id=tenant_id,
215+
user_id=user_id,
216+
agent_id=str(agent_id),
217+
)

backend/utils/memory_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ def build_memory_config(tenant_id: str) -> Dict[str, Any]:
2929
raise ValueError("ES_HOST must include scheme, host and port, e.g. http://host:9200")
3030
es_host = f"{parsed.scheme}://{parsed.hostname}"
3131
es_port = parsed.port
32+
index_name = (
33+
f"mem0_{embed_raw['model_repo'].lower()}_{embed_raw['model_name'].lower()}_{embed_raw['max_tokens']}"
34+
if embed_raw["model_repo"]
35+
else f"mem0_{embed_raw['model_name'].lower()}_{embed_raw['max_tokens']}"
36+
)
3237

3338
# 3. Assemble final configuration
3439
memory_config: Dict[str, Any] = {
@@ -52,7 +57,7 @@ def build_memory_config(tenant_id: str) -> Dict[str, Any]:
5257
"vector_store": {
5358
"provider": "elasticsearch",
5459
"config": {
55-
"collection_name": "mem0",
60+
"collection_name": index_name,
5661
"host": es_host,
5762
"port": es_port,
5863
"embedding_model_dims": embed_raw["max_tokens"],

0 commit comments

Comments
 (0)