syntaxmatrix 2.2.7__tar.gz → 2.2.9__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.2.7 → syntaxmatrix-2.2.9}/PKG-INFO +1 -1
  2. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/SyntaxMatrix.egg-info/PKG-INFO +1 -1
  3. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/setup.py +1 -1
  4. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/__init__.py +2 -2
  5. syntaxmatrix-2.2.9/syntaxmatrix/project_root.py +135 -0
  6. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/routes.py +27 -42
  7. syntaxmatrix-2.2.7/syntaxmatrix/project_root.py +0 -72
  8. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/LICENSE.txt +0 -0
  9. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/README.md +0 -0
  10. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/SyntaxMatrix.egg-info/SOURCES.txt +0 -0
  11. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/SyntaxMatrix.egg-info/dependency_links.txt +0 -0
  12. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/SyntaxMatrix.egg-info/requires.txt +0 -0
  13. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/SyntaxMatrix.egg-info/top_level.txt +0 -0
  14. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/pyproject.toml +0 -0
  15. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/setup.cfg +0 -0
  16. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/auth.py +0 -0
  17. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/bootstrap.py +0 -0
  18. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/commentary.py +0 -0
  19. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/core.py +0 -0
  20. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/db.py +0 -0
  21. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/display.py +0 -0
  22. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/emailer.py +0 -0
  23. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/file_processor.py +0 -0
  24. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/generate_page.py +0 -0
  25. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/gpt_models_latest.py +0 -0
  26. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/history_store.py +0 -0
  27. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/kernel_manager.py +0 -0
  28. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/llm_store.py +0 -0
  29. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/model_templates.py +0 -0
  30. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/models.py +0 -0
  31. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/plottings.py +0 -0
  32. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/profiles.py +0 -0
  33. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/session.py +0 -0
  34. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/settings/__init__.py +0 -0
  35. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/settings/default.yaml +0 -0
  36. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/settings/logging.py +0 -0
  37. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/settings/model_map.py +0 -0
  38. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/settings/prompts.py +0 -0
  39. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/settings/string_navbar.py +0 -0
  40. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/smiv.py +0 -0
  41. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/smpv.py +0 -0
  42. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/css/style.css +0 -0
  43. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/docs.md +0 -0
  44. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/icons/favicon.png +0 -0
  45. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/icons/hero_bg.jpg +0 -0
  46. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/icons/logo.png +0 -0
  47. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/icons/svg_497526.svg +0 -0
  48. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/icons/svg_497528.svg +0 -0
  49. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/js/chat.js +0 -0
  50. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/js/sidebar.js +0 -0
  51. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/static/js/widgets.js +0 -0
  52. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/templates/code_cell.html +0 -0
  53. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/templates/dashboard.html +0 -0
  54. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/templates/docs.html +0 -0
  55. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/templates/error.html +0 -0
  56. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/templates/login.html +0 -0
  57. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/templates/register.html +0 -0
  58. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/themes.py +0 -0
  59. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/ui_modes.py +0 -0
  60. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/utils.py +0 -0
  61. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vector_db.py +0 -0
  62. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/__init__.py +0 -0
  63. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/adapters/__init__.py +0 -0
  64. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/adapters/milvus_adapter.py +0 -0
  65. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/adapters/pgvector_adapter.py +0 -0
  66. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/adapters/sqlite_adapter.py +0 -0
  67. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/base.py +0 -0
  68. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectordb/registry.py +0 -0
  69. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/vectorizer.py +0 -0
  70. {syntaxmatrix-2.2.7 → syntaxmatrix-2.2.9}/syntaxmatrix/workspace_db.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syntaxmatrix
3
- Version: 2.2.7
3
+ Version: 2.2.9
4
4
  Summary: SyntaxMUI: A customizable framework for Python AI Assistant Projects.
5
5
  Home-page: https://github.com/bobganti/syntaxmatrix_demo
6
6
  Author: Bob Nti
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syntaxmatrix
3
- Version: 2.2.7
3
+ Version: 2.2.9
4
4
  Summary: SyntaxMUI: A customizable framework for Python AI Assistant Projects.
5
5
  Home-page: https://github.com/bobganti/syntaxmatrix_demo
6
6
  Author: Bob Nti
@@ -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.2.7",
11
+ version="2.2.9",
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.",
@@ -59,6 +59,6 @@ stream_write = _app_instance.stream_write
59
59
  enable_stream = _app_instance.enable_stream
60
60
  stream = _app_instance.stream
61
61
  get_stream_args = _app_instance.get_stream_args
62
- # set_stream_args = _app_instance.set_stream_args
63
62
 
64
- app = _app_instance.app
63
+
64
+ app = _app_instance.app
@@ -0,0 +1,135 @@
1
+ # syntaxmatrix/project_root.py
2
+ import os
3
+ import inspect
4
+ from pathlib import Path
5
+ import syntaxmatrix
6
+
7
+ def scandir() -> Path:
8
+ framework_dir = Path(syntaxmatrix.__file__).resolve().parent
9
+ for frame in inspect.stack():
10
+ fname = frame.filename
11
+ if not fname or not isinstance(fname, str):
12
+ continue
13
+ p = Path(fname)
14
+ try:
15
+ if p.is_file() and framework_dir not in p.parents:
16
+ return p.parent
17
+ except Exception:
18
+ continue
19
+ return framework_dir
20
+
21
+ def _writable(p: Path) -> bool:
22
+ try:
23
+ p.mkdir(parents=True, exist_ok=True)
24
+ test = p / ".smx_write_test"
25
+ with open(test, "w", encoding="utf-8") as f:
26
+ f.write("ok")
27
+ test.unlink(missing_ok=True)
28
+ return True
29
+ except Exception:
30
+ return False
31
+
32
+ def detect_project_root() -> Path:
33
+ """
34
+ Return the consumer project's 'syntaxmatrixdir' folder, creating it if necessary.
35
+ Resolution order:
36
+ 1) SMX_CLIENT_DIR (if set and writable)
37
+ 2) ./syntaxmatrixdir under current working dir (if writable)
38
+ 3) GCS Fuse standard mounts (if present & writable)
39
+ 4) /tmp/syntaxmatrixdir (always writable on Cloud Run)
40
+ 5) Fallback near the first non-framework caller (if writable)
41
+ """
42
+
43
+ # 1) Explicit override (keeps your local stable; handy in Cloud Run)
44
+ env = os.environ.get("SMX_CLIENT_DIR")
45
+ if env:
46
+ p = Path(env)
47
+ if _writable(p):
48
+ return p
49
+
50
+ # 2) CWD-based
51
+ cwd = Path.cwd()
52
+ p = cwd / "syntaxmatrixdir"
53
+ if _writable(p):
54
+ return p
55
+
56
+ # 3) Common GCS Fuse mount points (Gen2)
57
+ for candidate in [Path("/mnt/gcs/syntaxmatrixdir"),
58
+ Path("/mnt/disks/gcs/syntaxmatrixdir")]:
59
+ if _writable(candidate):
60
+ return candidate
61
+
62
+ # 4) Cloud Run safe default
63
+ tmp = Path("/tmp/syntaxmatrixdir")
64
+ if _writable(tmp):
65
+ return tmp
66
+
67
+ # 5) Fallback alongside caller
68
+ fallback = scandir() / "syntaxmatrixdir"
69
+ if _writable(fallback):
70
+ return fallback
71
+
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
@@ -45,15 +45,14 @@ except Exception:
45
45
  _HAVE_PYGMENTS = False
46
46
 
47
47
 
48
- # _CLIENT_DIR = detect_project_root()
49
- _CLIENT_DIR = Path(os.environ.get("SMX_CLIENT_DIR", "/app/syntaxmatrixdir"))
48
+ _CLIENT_DIR = detect_project_root()
50
49
  _stream_q = queue.Queue()
51
50
  _stream_cancelled = {}
52
51
  _last_result_html = {} # { session_id: html_doc }
53
52
 
54
- # store per-client so it stays alongside uploads
55
- MLEARNING_OUTPUTS = os.path.join(_CLIENT_DIR, "mlearning_outputs")
56
- os.makedirs(MLEARNING_OUTPUTS, exist_ok=True)
53
+ # # store per-client so it stays alongside uploads
54
+ # MLEARNING_OUTPUTS = os.path.join(_CLIENT_DIR, "mlearning_outputs")
55
+ # os.makedirs(MLEARNING_OUTPUTS, exist_ok=True)
57
56
 
58
57
  # single, reused formatter: inline styles, padding, rounded corners, scroll
59
58
  _FMT = _HtmlFmt(
@@ -5389,30 +5388,13 @@ def setup_routes(smx):
5389
5388
  # 2.4 Append a single download button (explicit click → fetch → download)
5390
5389
  download_url = url_for("download_result_html", session_id=session_id)
5391
5390
  dl_html = f"""
5392
- <button type="button"
5393
- class="btn"
5394
- style="margin:14px 0;padding:8px 12px;border:1px solid #0b6;border-radius:6px;background:#fff;color:#0b6;cursor:pointer;"
5395
- onclick="(async function(btn) {{
5396
- try {{
5397
- btn.disabled = true;
5398
- const orig = btn.textContent;
5399
- btn.textContent = 'Saving…';
5400
- const resp = await fetch('{download_url}', {{
5401
- method: 'POST',
5402
- headers: {{ 'X-Requested-With': 'fetch' }}
5403
- }});
5404
- const data = await resp.json();
5405
- if (!resp.ok || !data.ok) throw new Error(data.error || 'Save failed');
5406
- btn.textContent = 'Saved to MLEARNING_OUTPUTS';
5407
- }} catch (err) {{
5408
- console.error(err);
5409
- alert('Could not save. Please try again.');
5410
- }} finally {{
5411
- btn.disabled = false;
5412
- }}
5413
- }})(this)">
5414
- Download
5415
- </button>
5391
+ <a href="{download_url}">
5392
+ <button type="button"
5393
+ class="btn"
5394
+ style="margin:14px 0;padding:8px 12px;border:1px solid #0b6;border-radius:6px;background:#fff;color:#0b6;cursor:pointer;">
5395
+ Download
5396
+ </button>
5397
+ </a>
5416
5398
  """
5417
5399
  ai_outputs.append(Markup(dl_html))
5418
5400
 
@@ -5490,26 +5472,29 @@ def setup_routes(smx):
5490
5472
  data_cells=data_cells,
5491
5473
  session_id=session_id,
5492
5474
  )
5475
+
5493
5476
 
5494
-
5495
- @smx.app.route("/download/result/html/<session_id>", methods=["POST"])
5477
+ @smx.app.route("/download/result/html/<session_id>", methods=["GET"])
5496
5478
  def download_result_html(session_id):
5497
- """Send the last-built result HTML as a download (only when user clicks)."""
5498
- os.makedirs(MLEARNING_OUTPUTS, exist_ok=True)
5499
- stamp = datetime.now().strftime("%Y%m%d-%H%M%S-%f")
5500
- filename = f"result_{session_id}_{stamp}.html"
5501
- path = os.path.join(MLEARNING_OUTPUTS, filename)
5502
-
5479
+ """Stream the last-built result HTML as a browser download (no server save)."""
5503
5480
  html_doc = _last_result_html.get(session_id)
5504
5481
  if not html_doc:
5505
- return jsonify({"ok": False, "error": "No result available."}), 404
5506
- with open(path, "w", encoding="utf-8") as f:
5507
- f.write(html_doc)
5482
+ return ("No result available.", 404)
5508
5483
 
5509
- # free memory for this session copy (optional)
5484
+ buf = io.BytesIO(html_doc.encode("utf-8"))
5485
+ buf.seek(0)
5486
+
5487
+ # keep a copy if you wish, or free it:
5510
5488
  _last_result_html.pop(session_id, None)
5511
5489
 
5512
- return jsonify({"ok": True, "path": path})
5490
+ stamp = datetime.now().strftime("%Y%m%d-%H%M%S-%f")
5491
+ filename = f"result_{session_id}_{stamp}.html"
5492
+ return send_file(
5493
+ buf,
5494
+ mimetype="text/html; charset=utf-8",
5495
+ as_attachment=True,
5496
+ download_name=filename
5497
+ )
5513
5498
 
5514
5499
  # ── UPLOAD DATASET --------------------------------------
5515
5500
  @smx.app.route("/dashboard/upload", methods=["POST"])
@@ -1,72 +0,0 @@
1
- # syntaxmatrix/project_root.py
2
-
3
- import os
4
- import inspect
5
- from pathlib import Path
6
- import syntaxmatrix
7
-
8
-
9
- def _is_writable(d: Path) -> bool:
10
- """
11
- Try to create the directory and a tiny test file, then remove it.
12
- Returns True if writes work on this path (expected for a GCS mount).
13
- """
14
- try:
15
- d.mkdir(parents=True, exist_ok=True)
16
- probe = d / ".smx_write_probe"
17
- with open(probe, "w", encoding="utf-8") as f:
18
- f.write("ok")
19
- try:
20
- probe.unlink()
21
- except Exception:
22
- pass
23
- return True
24
- except Exception:
25
- return False
26
-
27
-
28
- def _caller_project_dir() -> Path:
29
- """
30
- Find the first stack frame outside the syntaxmatrix package and
31
- return its parent folder (best local fallback for dev).
32
- """
33
- framework_dir = Path(syntaxmatrix.__file__).resolve().parent
34
- for frame in inspect.stack():
35
- fn = frame.filename or ""
36
- p = Path(fn).resolve()
37
- try:
38
- p.relative_to(framework_dir)
39
- continue # skip framework files
40
- except Exception:
41
- pass
42
- if p.exists() and p.suffix == ".py":
43
- return p.parent
44
- return Path.cwd()
45
-
46
-
47
- def detect_project_root() -> Path:
48
- """
49
- Choose the single source-of-truth for all framework data (uploads, db, media):
50
- 1) Honour SMX_CLIENT_DIR if provided (Cloud Run: set to /app/syntaxmatrixdir).
51
- 2) If not set, prefer the standard Cloud Run mount path /app/syntaxmatrixdir.
52
- 3) Otherwise fall back to a local 'syntaxmatrixdir' beside the caller (dev only).
53
-
54
- NOTE: We intentionally avoid using any other container paths to keep all I/O
55
- on the bucket mount when running on Cloud Run.
56
- """
57
- # 1) Explicit environment override
58
- env_dir = os.environ.get("SMX_CLIENT_DIR", "").strip()
59
- if env_dir:
60
- d = Path(env_dir).expanduser().resolve()
61
- if _is_writable(d):
62
- return d
63
-
64
- # 2) Default Cloud Run mount path (as used in your deploy script)
65
- cloud_run_mount = Path("/app/syntaxmatrixdir")
66
- if _is_writable(cloud_run_mount):
67
- return cloud_run_mount
68
-
69
- # 3) Dev fallback: a local folder next to the app
70
- local_dir = _caller_project_dir() / "syntaxmatrixdir"
71
- local_dir.mkdir(parents=True, exist_ok=True)
72
- return local_dir
File without changes
File without changes
File without changes