syntaxmatrix 2.3.2__tar.gz → 2.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/PKG-INFO +1 -1
  2. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/SyntaxMatrix.egg-info/PKG-INFO +1 -1
  3. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/SyntaxMatrix.egg-info/SOURCES.txt +0 -1
  4. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/setup.py +1 -1
  5. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/__init__.py +0 -1
  6. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/auth.py +2 -3
  7. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/core.py +40 -62
  8. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/history_store.py +1 -1
  9. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/llm_store.py +1 -1
  10. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/project_root.py +1 -63
  11. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/routes.py +180 -193
  12. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/templates/dashboard.html +0 -1
  13. syntaxmatrix-2.3.5/syntaxmatrix/templates/docs.html +71 -0
  14. syntaxmatrix-2.3.2/syntaxmatrix/static/icons/hero_bg.jpg +0 -0
  15. syntaxmatrix-2.3.2/syntaxmatrix/templates/docs.html +0 -72
  16. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/LICENSE.txt +0 -0
  17. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/README.md +0 -0
  18. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/SyntaxMatrix.egg-info/dependency_links.txt +0 -0
  19. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/SyntaxMatrix.egg-info/requires.txt +0 -0
  20. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/SyntaxMatrix.egg-info/top_level.txt +0 -0
  21. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/pyproject.toml +0 -0
  22. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/setup.cfg +0 -0
  23. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/bootstrap.py +0 -0
  24. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/commentary.py +0 -0
  25. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/db.py +0 -0
  26. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/display.py +0 -0
  27. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/emailer.py +0 -0
  28. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/file_processor.py +0 -0
  29. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/generate_page.py +0 -0
  30. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/gpt_models_latest.py +0 -0
  31. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/kernel_manager.py +0 -0
  32. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/model_templates.py +0 -0
  33. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/models.py +0 -0
  34. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/plottings.py +0 -0
  35. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/profiles.py +0 -0
  36. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/session.py +0 -0
  37. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/settings/__init__.py +0 -0
  38. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/settings/default.yaml +0 -0
  39. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/settings/logging.py +0 -0
  40. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/settings/model_map.py +0 -0
  41. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/settings/prompts.py +0 -0
  42. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/settings/string_navbar.py +0 -0
  43. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/smiv.py +0 -0
  44. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/smpv.py +0 -0
  45. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/css/style.css +0 -0
  46. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/docs.md +0 -0
  47. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/icons/favicon.png +0 -0
  48. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/icons/logo.png +0 -0
  49. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/icons/svg_497526.svg +0 -0
  50. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/icons/svg_497528.svg +0 -0
  51. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/js/chat.js +0 -0
  52. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/js/sidebar.js +0 -0
  53. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/static/js/widgets.js +0 -0
  54. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/templates/code_cell.html +0 -0
  55. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/templates/error.html +0 -0
  56. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/templates/login.html +0 -0
  57. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/templates/register.html +0 -0
  58. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/themes.py +0 -0
  59. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/ui_modes.py +0 -0
  60. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/utils.py +0 -0
  61. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vector_db.py +0 -0
  62. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/__init__.py +0 -0
  63. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/adapters/__init__.py +0 -0
  64. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/adapters/milvus_adapter.py +0 -0
  65. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/adapters/pgvector_adapter.py +0 -0
  66. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/adapters/sqlite_adapter.py +0 -0
  67. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/base.py +0 -0
  68. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectordb/registry.py +0 -0
  69. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/vectorizer.py +0 -0
  70. {syntaxmatrix-2.3.2 → syntaxmatrix-2.3.5}/syntaxmatrix/workspace_db.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syntaxmatrix
3
- Version: 2.3.2
3
+ Version: 2.3.5
4
4
  Summary: SyntaxMUI: A customizable framework for Python AI Assistant Projects.
5
5
  Author: Bob Nti
6
6
  Author-email: bob.nti@syntaxmatrix.com
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syntaxmatrix
3
- Version: 2.3.2
3
+ Version: 2.3.5
4
4
  Summary: SyntaxMUI: A customizable framework for Python AI Assistant Projects.
5
5
  Author: Bob Nti
6
6
  Author-email: bob.nti@syntaxmatrix.com
@@ -50,7 +50,6 @@ syntaxmatrix/settings/string_navbar.py
50
50
  syntaxmatrix/static/docs.md
51
51
  syntaxmatrix/static/css/style.css
52
52
  syntaxmatrix/static/icons/favicon.png
53
- syntaxmatrix/static/icons/hero_bg.jpg
54
53
  syntaxmatrix/static/icons/logo.png
55
54
  syntaxmatrix/static/icons/svg_497526.svg
56
55
  syntaxmatrix/static/icons/svg_497528.svg
@@ -8,7 +8,7 @@ with open(os.path.join(this_directory, "README.md"), encoding="utf-8") as f:
8
8
 
9
9
  setup(
10
10
  name="syntaxmatrix",
11
- version="2.3.2",
11
+ version="2.3.5",
12
12
  author="Bob Nti",
13
13
  author_email="bob.nti@syntaxmatrix.com",
14
14
  description="SyntaxMUI: A customizable framework for Python AI Assistant Projects.",
@@ -26,7 +26,6 @@ warning = _app_instance.warning
26
26
  set_user_icon = _app_instance.set_user_icon
27
27
  set_bot_icon = _app_instance.set_bot_icon
28
28
  set_favicon = _app_instance.set_favicon
29
- get_favicon = _app_instance.get_favicon
30
29
  set_project_name = _app_instance.set_project_name
31
30
  set_site_title = _app_instance.set_site_title
32
31
  set_site_logo = _app_instance.set_site_logo
@@ -75,9 +75,9 @@ def init_auth_db():
75
75
  if not row:
76
76
  # (a) generate or read the one-off password file
77
77
  fw_data_dir = _CLIENT_DIR # returns Path to <project>/.syntaxmatrix
78
- cred_file = fw_data_dir / "superadmin_creds.txt"
78
+ cred_file = fw_data_dir / "superadmin_credentials.txt"
79
79
 
80
- superadmin_email = "ceo@syntaxmatrix.sx"
80
+ superadmin_email = "ceo@syntaxmatrix.ceo"
81
81
  superadmin_username = "ceo"
82
82
 
83
83
  if cred_file.exists():
@@ -286,7 +286,6 @@ def set_user_role(actor_role: str, user_id: int, role_name: str) -> bool:
286
286
  conn.close()
287
287
 
288
288
 
289
-
290
289
  def register_user(email:str, username:str, password:str, role:str = "user") -> bool:
291
290
  """Return True if registration succeeded, False if username taken."""
292
291
  hashed = generate_password_hash(password)
@@ -30,25 +30,28 @@ from threading import RLock
30
30
  # this ensures the key & data always live under the package dir,
31
31
  # regardless of where the developer `cd` into before launching.
32
32
  _CLIENT_DIR = detect_project_root()
33
- _HISTORY_DIR = os.path.join(_CLIENT_DIR, "data", "smx_history")
33
+ _HISTORY_DIR = os.path.join(_CLIENT_DIR, "smx_history")
34
34
  os.makedirs(_HISTORY_DIR, exist_ok=True)
35
35
 
36
- _SECRET_PATH = os.path.join(_CLIENT_DIR, "data", ".smx_secret_key")
36
+ _SECRET_PATH = os.path.join(_CLIENT_DIR, ".smx_secret_key")
37
37
 
38
- dotenv_path = os.path.join(str(_CLIENT_DIR.parent), ".env")
39
- if os.path.isfile(dotenv_path):
40
- load_dotenv(dotenv_path, override=True)
38
+ _CLIENT_DOTENV_PATH = os.path.join(str(_CLIENT_DIR.parent), ".env")
39
+ if os.path.isfile(_CLIENT_DOTENV_PATH):
40
+ load_dotenv(_CLIENT_DOTENV_PATH, override=True)
41
+
42
+ _ICONS_PATH = os.path.join(_CLIENT_DIR, "static", "icons")
43
+ os.makedirs(_ICONS_PATH, exist_ok=True)
41
44
 
42
45
  EDA_OUTPUT = {} # global buffer for EDA output by session
43
46
 
44
47
  class SyntaxMUI:
45
48
  def __init__(self,
46
49
  host="127.0.0.1",
47
- port="5050",
50
+ port="5080",
48
51
  user_icon="👩🏿‍🦲",
49
- bot_icon="/static/icons/favicon.png",
52
+ bot_icon="<img src='/static/icons/logo.png' width='15' alt='bot'/>",
50
53
  favicon="/static/icons/favicon.png",
51
- site_logo="/static/icons/favicon.png",
54
+ site_logo="<img src='/static/icons/logo.png' width='30' alt='logo'/>",
52
55
  site_title="SyntaxMatrix",
53
56
  project_name="smxAI",
54
57
  theme_name="light",
@@ -60,9 +63,9 @@ class SyntaxMUI:
60
63
 
61
64
  self.get_app_secrete()
62
65
  self.user_icon = user_icon
63
- self.bot_icon = f"<img src='{bot_icon}' width='20' alt='bot'/>"
64
- self.site_logo = f"<img src='{site_logo}' width='30' alt='logo'/>"
65
- self.favicon = f"<link rel='icon' type='image/png' href='{favicon}'/>"
66
+ self.bot_icon = bot_icon
67
+ self.site_logo = site_logo
68
+ self.favicon = favicon
66
69
  self.site_title = site_title
67
70
  self.project_name = project_name
68
71
  self.ui_mode = ui_mode
@@ -107,7 +110,7 @@ class SyntaxMUI:
107
110
  if not app.secret_key:
108
111
  app.secret_key = secrets.token_urlsafe(32)
109
112
 
110
- def get_app_secrete(self): # keeping your name
113
+ def get_app_secrete(self):
111
114
  if os.path.exists(_SECRET_PATH):
112
115
  self.app.secret_key = open(_SECRET_PATH, "r", encoding="utf-8").read().strip()
113
116
  else:
@@ -317,19 +320,14 @@ class SyntaxMUI:
317
320
  def set_project_name(self, project_name):
318
321
  self.project_name = project_name
319
322
 
320
- @staticmethod
321
- def set_favicon(self, favicon):
322
- self.favicon = favicon
323
-
324
- def get_favicon(self):
325
- return self.favicon
323
+ def set_favicon(self, icon):
324
+ self.favicon = icon
326
325
 
327
326
  def set_site_logo(self, logo):
328
- self.site_logo = logo if str(logo).strip().startswith("<") else f"<img src='{logo}' width='30' alt='SMX Logo'/>"
327
+ self.site_logo = logo
329
328
 
330
329
  def set_user_icon(self, icon):
331
- self.user_icon = icon
332
- return _CLIENT_DIR
330
+ self.user_icon = icon
333
331
 
334
332
  def set_bot_icon(self, icon):
335
333
  self.bot_icon = icon
@@ -396,64 +394,44 @@ class SyntaxMUI:
396
394
  session.modified = True
397
395
  return sid
398
396
 
399
-
400
397
  def get_chat_history(self) -> list[tuple[str, str]]:
401
- # now load the history for the _current_ chat session
398
+ # Load the history for the _current_ chat session
402
399
  sid = self._sid()
403
400
  cid = self.get_session_id()
401
+ if session.get("user_id"):
402
+ # Logged-in: use SQLHistoryStore (Store). Locking handled inside history_store.py
403
+ return Store.load(str(session["user_id"]), cid)
404
+ # Anonymous: use PersistentHistoryStore (_Store) JSON files
404
405
  return _Store.load(sid, cid)
405
-
406
+
406
407
 
407
408
  def set_chat_history(self, history: list[tuple[str, str]], *, max_items: int | None = None) -> list[tuple[str, str]]:
408
409
  sid = self._sid()
409
410
  cid = self.get_session_id()
410
- _Store.save(sid, cid, history)
411
- session["chat_history"] = history[-30:] # still mirror a thin copy into Flask’s session cookie for the UI
412
- session.modified = True
413
-
414
411
  if session.get("user_id"):
415
- user_id = session["user_id"]
416
- cid = session["current_session"]["id"]
417
- title = session["current_session"]["title"]
418
- # persist both title + history
419
- Store.save(user_id, cid, history, title)
420
-
421
- return history if max_items is None else history[-max_items:]
412
+ # Logged-in: chats.db via Store (SQLHistoryStore)
413
+ Store.save(str(session["user_id"]), cid, history)
414
+ else:
415
+ # Anonymous: file-backed via _Store (PersistentHistoryStore)
416
+ _Store.save(sid, cid, history)
422
417
 
423
418
 
424
419
  def clear_chat_history(self):
425
- """
426
- Clear both the UI slice *and* the server-side history bucket
427
- for this session_id + chat_id.
428
- """
429
420
  if has_request_context():
430
421
  sid = self._sid()
431
422
  cid = self.get_session_id()
432
423
 
433
- # wipe server history for this chat
434
- _Store.save(sid, cid, [])
435
-
436
- # clear UI mirror
437
- session["chat_history"] = []
438
-
439
- # clear EDA panel for this chat id
440
- try:
441
- with self._eda_lock:
442
- self._eda_output.pop(cid, None)
443
- except Exception:
444
- pass
424
+ # delete the chat from the correct backend (DB for logged-in, file for anonymous)
425
+ if session.get("user_id"):
426
+ Store.delete(session["user_id"], cid)
427
+ else:
428
+ _Store.delete(sid, cid)
445
429
 
446
- if "current_session" in session:
447
- session["current_session"]["history"] = []
448
- if "past_sessions" in session:
449
- session["past_sessions"] = [
450
- {**s, "history": []} if s.get("id") == cid else s
451
- for s in session["past_sessions"]
452
- ]
430
+ # rotate to a fresh empty chat (session remains metadata-only)
431
+ new_cid = str(uuid.uuid4())
432
+ session["current_session"] = {"id": new_cid, "title": "Current"}
433
+ session["active_chat_id"] = new_cid
453
434
  session.modified = True
454
- else:
455
- self._fallback_chat_history = []
456
-
457
435
 
458
436
  def bot_message(self, content, max_length=20):
459
437
  history = self.get_chat_history()
@@ -1242,7 +1220,7 @@ class SyntaxMUI:
1242
1220
 
1243
1221
  return code.strip()
1244
1222
 
1245
-
1223
+
1246
1224
  def sanitize_rough_to_markdown_task(self, rough: str) -> str:
1247
1225
  """
1248
1226
  Return only the Task text (no tags).
@@ -11,7 +11,7 @@ from syntaxmatrix.project_root import detect_project_root
11
11
 
12
12
  _CLIENT_DIR = detect_project_root()
13
13
  # ——— Anonymous-user JSON fallback store ——————————————
14
- _fallback_dir = os.path.join(_CLIENT_DIR, "data", "smx_history")
14
+ _fallback_dir = os.path.join(_CLIENT_DIR, "smx_history")
15
15
  os.makedirs(_fallback_dir, exist_ok=True)
16
16
 
17
17
  # Persist chats.db under dev app’s data/ directory
@@ -12,7 +12,7 @@ from syntaxmatrix.project_root import detect_project_root
12
12
  # Ensures a stable encryption key, no env var needed.
13
13
  # ------------------------------------------------------------------
14
14
  _CLIENT_DIR = detect_project_root()
15
- KEY_PATH = os.path.join(_CLIENT_DIR, "data", "fernet.key")
15
+ KEY_PATH = os.path.join(_CLIENT_DIR, "fernet.key")
16
16
  if os.path.exists(KEY_PATH):
17
17
  __FERNET = Fernet(open(KEY_PATH, "rb").read())
18
18
  else:
@@ -70,66 +70,4 @@ def detect_project_root() -> Path:
70
70
  return fallback
71
71
 
72
72
  # Last resort: return /tmp anyway (avoids import-time crashes)
73
- return tmp
74
-
75
-
76
-
77
- # import os
78
- # import inspect
79
- # from pathlib import Path
80
- # import syntaxmatrix
81
-
82
-
83
- # def scandir() -> Path:
84
- # """
85
- # Find the first stack frame outside of the syntaxmatrix package
86
- # whose filename is a real .py file on disk, and return its parent dir.
87
- # """
88
- # framework_dir = Path(syntaxmatrix.__file__).resolve().parent
89
-
90
- # for frame in inspect.stack():
91
- # fname = frame.filename
92
-
93
- # # 1) skip internal frames (<frozen ...>) or empty names
94
- # if not fname or fname.startswith("<"):
95
- # continue
96
-
97
- # candidate = Path(fname)
98
-
99
- # # 2) skip non-.py or non-existent paths
100
- # if candidate.suffix != ".py" or not candidate.exists():
101
- # continue
102
-
103
- # try:
104
- # candidate = candidate.resolve()
105
- # except (OSError, RuntimeError):
106
- # # if for some reason resolve() fails, skip it
107
- # continue
108
-
109
- # # 3) skip anything inside the framework itself
110
- # if framework_dir in candidate.parents:
111
- # continue
112
-
113
- # # FOUND: a user file (e.g. app.py, manage.py, etc.)
114
- # return candidate.parent
115
-
116
- # # fallback: whatever cwd() is
117
- # return Path(os.getcwd()).resolve()
118
-
119
-
120
- # def detect_project_root() -> Path:
121
- # """
122
- # Returns the consumer project's syntaxmatrixdir folder, creating it if necessary.
123
- # All framework data & uploads live here.
124
- # """
125
- # # 1) First check the CWD (where your app:app is running)
126
- # cwd = Path.cwd()
127
- # candidate = cwd / "syntaxmatrixdir"
128
- # if candidate.exists():
129
- # return candidate
130
-
131
- # # 2) Otherwise fall back to the old logic (e.g. inside site-packages)
132
- # proj_root = scandir()
133
- # fw_root = proj_root / "syntaxmatrixdir"
134
- # fw_root.mkdir(exist_ok=True)
135
- # return fw_root
73
+ return tmp