syntaxmatrix-core 1.0.7__tar.gz → 1.0.8__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 (101) hide show
  1. {syntaxmatrix_core-1.0.7/syntaxmatrix_core.egg-info → syntaxmatrix_core-1.0.8}/PKG-INFO +1 -1
  2. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/setup.py +1 -1
  3. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/agentic/agents.py +7 -150
  4. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/core.py +11 -6
  5. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/page_builder_generation.py +10 -185
  6. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/page_layout_contract.py +7 -28
  7. syntaxmatrix_core-1.0.8/syntaxmatrix/premium/__init__.py +10 -0
  8. syntaxmatrix_core-1.0.8/syntaxmatrix/premium/gate.py +107 -0
  9. syntaxmatrix_core-1.0.7/syntaxmatrix/Rroutes.py → syntaxmatrix_core-1.0.8/syntaxmatrix/routes.py +9267 -9267
  10. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/settings/prompts.py +24 -170
  11. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/edit_page.html +44 -764
  12. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8/syntaxmatrix_core.egg-info}/PKG-INFO +1 -1
  13. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix_core.egg-info/SOURCES.txt +2 -2
  14. syntaxmatrix_core-1.0.7/syntaxmatrix/routes.py +0 -10158
  15. syntaxmatrix_core-1.0.7/syntaxmatrix/static/icons/bot_icon.png +0 -0
  16. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/MANIFEST.in +0 -0
  17. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/README.md +0 -0
  18. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/pyproject.toml +0 -0
  19. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/setup.cfg +0 -0
  20. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/__init__.py +0 -0
  21. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/agentic/__init__.py +0 -0
  22. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/agentic/agent_tools.py +0 -0
  23. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/agentic/agents_orchestrer.py +0 -0
  24. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/agentic/code_tools_registry.py +0 -0
  25. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/agentic/model_templates.py +0 -0
  26. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/auth.py +0 -0
  27. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/bootstrap.py +0 -0
  28. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/client_docs.py +0 -0
  29. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/commentary.py +0 -0
  30. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/dataset_preprocessing.py +0 -0
  31. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/db.py +0 -0
  32. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/db_backends/__init__.py +0 -0
  33. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/db_backends/postgres_backend.py +0 -0
  34. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/db_backends/sqlite_backend.py +0 -0
  35. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/db_contract.py +0 -0
  36. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/display_html.py +0 -0
  37. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/emailer.py +0 -0
  38. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/file_processor.py +0 -0
  39. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/gpt_models_latest.py +0 -0
  40. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/history_store.py +0 -0
  41. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/kernel_manager.py +0 -0
  42. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/llm_store.py +0 -0
  43. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/media/__init__.py +0 -0
  44. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/media/media_pixabay.py +0 -0
  45. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/models.py +0 -0
  46. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/page_builder_defaults.py +0 -0
  47. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/page_patch_publish.py +0 -0
  48. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/plottings.py +0 -0
  49. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/plugin_manager.py +0 -0
  50. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/preface.py +0 -0
  51. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/profiles.py +0 -0
  52. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/project_root.py +0 -0
  53. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/selftest_page_templates.py +0 -0
  54. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/session.py +0 -0
  55. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/settings/__init__.py +0 -0
  56. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/settings/client_items.py +0 -0
  57. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/settings/logging.py +0 -0
  58. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/settings/model_map.py +0 -0
  59. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/settings/string_navbar.py +0 -0
  60. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/smiv.py +0 -0
  61. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/smpv.py +0 -0
  62. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/assets/hero-default.svg +0 -0
  63. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/css/style.css +0 -0
  64. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/docs.md +0 -0
  65. /syntaxmatrix_core-1.0.7/syntaxmatrix/static/icons/bot_icon2.png → /syntaxmatrix_core-1.0.8/syntaxmatrix/static/icons/bot_icon.png +0 -0
  66. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/icons/favicon.png +0 -0
  67. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/icons/logo.png +0 -0
  68. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/icons/logo2.png +0 -0
  69. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/icons/svg_497526.svg +0 -0
  70. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/icons/svg_497528.svg +0 -0
  71. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/js/chat.js +0 -0
  72. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/js/sidebar.js +0 -0
  73. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/static/js/widgets.js +0 -0
  74. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/admin_billing.html +0 -0
  75. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/admin_branding.html +0 -0
  76. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/admin_features.html +0 -0
  77. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/admin_secretes.html +0 -0
  78. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/change_password.html +0 -0
  79. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/code_cell.html +0 -0
  80. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/dashboard.html +0 -0
  81. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/dataset_resize.html +0 -0
  82. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/docs.html +0 -0
  83. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/error.html +0 -0
  84. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/login.html +0 -0
  85. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/templates/register.html +0 -0
  86. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/themes.py +0 -0
  87. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/ui_modes.py +0 -0
  88. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/utils.py +0 -0
  89. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vector_db.py +0 -0
  90. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/__init__.py +0 -0
  91. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/adapters/__init__.py +0 -0
  92. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/adapters/milvus_adapter.py +0 -0
  93. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/adapters/pgvector_adapter.py +0 -0
  94. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/adapters/sqlite_adapter.py +0 -0
  95. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/base.py +0 -0
  96. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectordb/registry.py +0 -0
  97. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/vectorizer.py +0 -0
  98. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix/workspace_db.py +0 -0
  99. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix_core.egg-info/dependency_links.txt +0 -0
  100. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix_core.egg-info/requires.txt +0 -0
  101. {syntaxmatrix_core-1.0.7 → syntaxmatrix_core-1.0.8}/syntaxmatrix_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syntaxmatrix-core
3
- Version: 1.0.7
3
+ Version: 1.0.8
4
4
  Summary: SyntaxMatrix: A Framework for building owned AI Platform.
5
5
  Author: Bob Nti
6
6
  Author-email: info@syntaxmatrix.net
@@ -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-core",
11
- version="1.0.7",
11
+ version="1.0.8",
12
12
  license="MIT",
13
13
  classifiers=[
14
14
  "Operating System :: OS Independent",
@@ -629,7 +629,6 @@ def classify_ml_job_agent(refined_question, dataset_profile):
629
629
  # ─────────────────────────────────────────────────────────
630
630
  def agentic_generate_page(*,
631
631
  page_slug: str,
632
- page_kind: str = "",
633
632
  website_description: str,
634
633
  page_instructions: str = "",
635
634
  client_dir: str,
@@ -934,12 +933,7 @@ def agentic_generate_page(*,
934
933
  "text": "<string>",
935
934
  "icon": "<iconName or empty>",
936
935
  "imgQuery": "<search query or empty>",
937
- "needsImage": true|false,
938
- "price": "<optional pricing string>",
939
- "priceSuffix": "<optional pricing suffix>",
940
- "ctaLabel": "<optional card CTA label>",
941
- "ctaHref": "<optional card CTA href>",
942
- "featured": true|false
936
+ "needsImage": true|false
943
937
  }}
944
938
  ]
945
939
  }}
@@ -1334,102 +1328,6 @@ def agentic_generate_page(*,
1334
1328
  secs.insert(hero_idx + 1, new_sec)
1335
1329
 
1336
1330
 
1337
- # TEMPLATE_SPECS = {
1338
- # "generic_v1": {
1339
- # "category": "landing",
1340
- # "template": {"id": "generic_v1", "version": "1.0.0"},
1341
- # "allowed_section_types": ["hero", "features", "gallery", "testimonials", "faq", "cta", "richtext"],
1342
- # "required_sections": [],
1343
- # "min_sections": 4,
1344
- # "max_sections": 7,
1345
- # "min_images": 6,
1346
- # "max_images": 9,
1347
- # },
1348
- # "services_grid_v1": {
1349
- # "category": "services",
1350
- # "template": {"id": "services_grid_v1", "version": "1.0.0"},
1351
- # "allowed_section_types": ["hero", "services", "process", "proof", "faq", "cta", "richtext"],
1352
- # "required_sections": [
1353
- # {"id": "sec_hero", "type": "hero"},
1354
- # {"id": "sec_services", "type": "services"},
1355
- # {"id": "sec_process", "type": "process"},
1356
- # {"id": "sec_proof", "type": "proof"},
1357
- # {"id": "sec_faq", "type": "faq"},
1358
- # {"id": "sec_cta", "type": "cta"},
1359
- # ],
1360
- # "min_sections": 6,
1361
- # "max_sections": 6,
1362
- # "min_images": 6,
1363
- # "max_images": 9,
1364
- # },
1365
- # "services_detail_v1": {
1366
- # "category": "services",
1367
- # "template": {"id": "services_detail_v1", "version": "1.0.0"},
1368
- # "allowed_section_types": ["hero", "offers", "comparison", "process", "case_studies", "faq", "cta", "richtext"],
1369
- # "required_sections": [
1370
- # {"id": "sec_hero", "type": "hero"},
1371
- # {"id": "sec_offers", "type": "offers"},
1372
- # {"id": "sec_comparison", "type": "comparison"},
1373
- # {"id": "sec_process", "type": "process"},
1374
- # {"id": "sec_case_studies", "type": "case_studies"},
1375
- # {"id": "sec_faq", "type": "faq"},
1376
- # {"id": "sec_cta", "type": "cta"},
1377
- # ],
1378
- # "min_sections": 7,
1379
- # "max_sections": 7,
1380
- # "min_images": 6,
1381
- # "max_images": 9,
1382
- # },
1383
- # "about_glass_hero_v1": {
1384
- # "category": "about",
1385
- # "template": {"id": "about_glass_hero_v1", "version": "1.0.0"},
1386
- # "allowed_section_types": ["hero", "story", "values", "logos", "team", "testimonials", "faq", "cta", "richtext"],
1387
- # "required_sections": [
1388
- # {"id": "sec_hero", "type": "hero"},
1389
- # {"id": "sec_story", "type": "story"},
1390
- # {"id": "sec_values", "type": "values"},
1391
- # {"id": "sec_cta", "type": "cta"},
1392
- # ],
1393
- # "min_sections": 4,
1394
- # "max_sections": 7,
1395
- # "min_images": 6,
1396
- # "max_images": 9,
1397
- # },
1398
- # "gallery_rail_v1": {
1399
- # "category": "gallery",
1400
- # "template": {"id": "gallery_rail_v1", "version": "1.0.0"},
1401
- # "allowed_section_types": ["hero", "gallery", "testimonials", "faq", "cta", "richtext"],
1402
- # "required_sections": [
1403
- # {"id": "sec_hero", "type": "hero"},
1404
- # {"id": "sec_gallery", "type": "gallery"},
1405
- # {"id": "sec_cta", "type": "cta"},
1406
- # ],
1407
- # "min_sections": 3,
1408
- # "max_sections": 6,
1409
- # "min_images": 6,
1410
- # "max_images": 9,
1411
- # },
1412
- # }
1413
-
1414
- # def _select_template_spec(slug: str, page_kind: str = "") -> dict:
1415
- # s = _slugify(slug)
1416
- # kind = _slugify(page_kind)
1417
- # key = f"{kind} {s}".strip()
1418
-
1419
- # if any(k in key for k in ("gallery", "portfolio", "showcase", "screenshots", "photos")):
1420
- # return TEMPLATE_SPECS["gallery_rail_v1"]
1421
-
1422
- # if any(k in key for k in ("services", "service", "solutions", "solution", "offerings")):
1423
- # if any(k in key for k in ("pricing", "plan", "plans", "package", "packages", "tier", "tiers")):
1424
- # return TEMPLATE_SPECS["services_detail_v1"]
1425
- # return TEMPLATE_SPECS["services_grid_v1"]
1426
-
1427
- # if "about" in key:
1428
- # return TEMPLATE_SPECS["about_glass_hero_v1"]
1429
-
1430
- # return TEMPLATE_SPECS["generic_v1"]
1431
-
1432
-
1433
1331
  TEMPLATE_SPECS = {
1434
1332
  "generic_v1": {
1435
1333
  "category": "landing",
@@ -1476,39 +1374,6 @@ def agentic_generate_page(*,
1476
1374
  "min_images": 6,
1477
1375
  "max_images": 9,
1478
1376
  },
1479
- "contact_form_v1": {
1480
- "category": "contact",
1481
- "template": {"id": "contact_form_v1", "version": "1.0.0"},
1482
- "allowed_section_types": ["hero", "richtext", "contact", "faq", "cta"],
1483
- "required_sections": [
1484
- {"id": "sec_hero", "type": "hero"},
1485
- {"id": "sec_intro", "type": "richtext"},
1486
- {"id": "sec_contact", "type": "contact"},
1487
- {"id": "sec_faq", "type": "faq"},
1488
- {"id": "sec_cta", "type": "cta"},
1489
- ],
1490
- "min_sections": 5,
1491
- "max_sections": 6,
1492
- "min_images": 4,
1493
- "max_images": 6,
1494
- },
1495
- "pricing_tiers_v1": {
1496
- "category": "pricing",
1497
- "template": {"id": "pricing_tiers_v1", "version": "1.0.0"},
1498
- "allowed_section_types": ["hero", "richtext", "pricing", "comparison", "faq", "cta"],
1499
- "required_sections": [
1500
- {"id": "sec_hero", "type": "hero"},
1501
- {"id": "sec_intro", "type": "richtext"},
1502
- {"id": "sec_pricing", "type": "pricing"},
1503
- {"id": "sec_comparison", "type": "comparison"},
1504
- {"id": "sec_faq", "type": "faq"},
1505
- {"id": "sec_cta", "type": "cta"},
1506
- ],
1507
- "min_sections": 6,
1508
- "max_sections": 6,
1509
- "min_images": 4,
1510
- "max_images": 6,
1511
- },
1512
1377
  "about_glass_hero_v1": {
1513
1378
  "category": "about",
1514
1379
  "template": {"id": "about_glass_hero_v1", "version": "1.0.0"},
@@ -1540,26 +1405,18 @@ def agentic_generate_page(*,
1540
1405
  },
1541
1406
  }
1542
1407
 
1543
- def _select_template_spec(slug: str, page_kind: str = "") -> dict:
1408
+ def _select_template_spec(slug: str) -> dict:
1544
1409
  s = _slugify(slug)
1545
- kind = _slugify(page_kind)
1546
- key = f"{kind} {s}".strip()
1547
-
1548
- if any(k in key for k in ("contact", "reach-us", "get-in-touch", "support")):
1549
- return TEMPLATE_SPECS["contact_form_v1"]
1550
-
1551
- if any(k in key for k in ("pricing", "plans", "plan", "tiers", "packages", "package")):
1552
- return TEMPLATE_SPECS["pricing_tiers_v1"]
1553
1410
 
1554
- if any(k in key for k in ("gallery", "portfolio", "showcase", "screenshots", "photos")):
1411
+ if any(k in s for k in ("gallery", "portfolio", "showcase", "screenshots", "photos")):
1555
1412
  return TEMPLATE_SPECS["gallery_rail_v1"]
1556
1413
 
1557
- if any(k in key for k in ("services", "service", "solutions", "solution", "offerings")):
1558
- if any(k in key for k in ("pricing", "plan", "plans", "package", "packages", "tier", "tiers")):
1414
+ if "service" in s:
1415
+ if any(k in s for k in ("pricing", "plan", "plans", "package", "packages", "tier", "tiers")):
1559
1416
  return TEMPLATE_SPECS["services_detail_v1"]
1560
1417
  return TEMPLATE_SPECS["services_grid_v1"]
1561
1418
 
1562
- if "about" in key:
1419
+ if "about" in s:
1563
1420
  return TEMPLATE_SPECS["about_glass_hero_v1"]
1564
1421
 
1565
1422
  return TEMPLATE_SPECS["generic_v1"]
@@ -2216,7 +2073,7 @@ def agentic_generate_page(*,
2216
2073
 
2217
2074
  notes = []
2218
2075
 
2219
- tpl_spec = _select_template_spec(page_slug, page_kind=page_kind)
2076
+ tpl_spec = _select_template_spec(page_slug)
2220
2077
  plan = _make_page_plan(
2221
2078
  page_slug=page_slug,
2222
2079
  website_description=website_description,
@@ -34,6 +34,7 @@ from syntaxmatrix.settings.prompts import(
34
34
  )
35
35
  from syntaxmatrix.settings.client_items import read_client_file, getenv_api_key
36
36
 
37
+ from .premium import FeatureGate
37
38
  from .plugin_manager import PluginManager
38
39
  from pathlib import Path
39
40
 
@@ -65,7 +66,7 @@ class SyntaxMUI:
65
66
  favicon="/static/icons/favicon.png",
66
67
  site_logo="<img src='/static/icons/logo.png' width='45' alt='logo'/>",
67
68
  site_title="SyntaxMatrix",
68
- project_name="smx-Asteria",
69
+ project_name="smxAI",
69
70
  theme_name="light",
70
71
  ui_mode = "default"
71
72
  ):
@@ -146,7 +147,12 @@ class SyntaxMUI:
146
147
  self.is_streaming = False
147
148
  self.stream_args = {}
148
149
  self._apply_feature_flags_from_db()
149
-
150
+ # Premium (entitlements + plugins). Safe no-op unless configured.
151
+ try:
152
+ self.feature_gate = FeatureGate(client_dir=_CLIENT_DIR, db=db)
153
+ except Exception:
154
+ self.feature_gate = FeatureGate(client_dir=_CLIENT_DIR)
155
+
150
156
  try:
151
157
  self.plugins = PluginManager(self, gate=self.feature_gate, db=db)
152
158
  self.plugins.load_all()
@@ -963,7 +969,6 @@ class SyntaxMUI:
963
969
  </p>
964
970
  """
965
971
  return None
966
-
967
972
  self.chat_profile = chat_profile
968
973
  self.chat_profile['client'] = _prof.get_client(chat_profile)
969
974
 
@@ -972,7 +977,7 @@ class SyntaxMUI:
972
977
  _model = self.chat_profile['model']
973
978
 
974
979
  _contents = f"""
975
- {self._default_smxai_instructions}\n\n
980
+ {self.smxai_instructions}\n\n
976
981
  Question: {query}\n
977
982
  Context: {context}\n\n
978
983
  History: {history}\n\n
@@ -996,7 +1001,7 @@ class SyntaxMUI:
996
1001
 
997
1002
  elif _provider == "openai" and _model in self.get_gpt_models_latest(): # GPt 5 series
998
1003
  input_prompt = (
999
- f"{self._default_smxai_instructions}\n\n"
1004
+ f"{self.smxai_instructions}\n\n"
1000
1005
  f"Generate a response to this query:\n{query}\n"
1001
1006
  f"based on this given context:\n{context}\n\n"
1002
1007
  f"(Use conversation continuity if available.)"
@@ -1053,7 +1058,7 @@ class SyntaxMUI:
1053
1058
  Login to the admin panel and add the LLM profile for chatting or contact your administrator.
1054
1059
  </p>
1055
1060
  """
1056
- return None
1061
+ return None
1057
1062
 
1058
1063
  self.chat_profile = chat_profile
1059
1064
  self.chat_profile['client'] = _prof.get_client(chat_profile)
@@ -867,8 +867,7 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
867
867
  .smxp .heroCard{border:1px solid var(--bd);border-radius:var(--r);background:var(--card);padding:14px}
868
868
  .smxp .btnRow{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px}
869
869
  .smxp .btn{display:inline-flex;gap:8px;align-items:center;border-radius:999px;padding:10px 14px;
870
- border:1px solid var(--bd);text-decoration:none;background:rgba(99,102,241,.12);cursor:pointer}
871
-
870
+ border:1px solid var(--bd);text-decoration:none;background:rgba(99,102,241,.12)}
872
871
  .smxp .btn:hover{transform:translateY(-1px)}
873
872
  .smxp .grid{display:grid;gap:12px}
874
873
  /* Mobile: force single-column grids (Page Studio pages only) */
@@ -992,7 +991,6 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
992
991
  position:relative;
993
992
  margin-left:-50vw;
994
993
  margin-right:-50vw;
995
-
996
994
  height:clamp(240px, 44vh, 520px);
997
995
  background-position:center;
998
996
  background-size:cover;
@@ -1009,6 +1007,15 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
1009
1007
  margin: 0 0 18px 0;
1010
1008
  }
1011
1009
 
1010
+ /* Card images: consistent crop */
1011
+ .smxp .card-img{
1012
+ width:100%;
1013
+ height:170px;
1014
+ object-fit:cover;
1015
+ border-radius:calc(var(--r) - 6px);
1016
+ display:block;
1017
+ }
1018
+
1012
1019
  /* Full-bleed section image (hero-like) */
1013
1020
  .smxp .sec-media{
1014
1021
  width:100vw;
@@ -1033,33 +1040,6 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
1033
1040
  display:block;
1034
1041
  }
1035
1042
 
1036
- .smxp .contact-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:16px;align-items:start}
1037
- @media (max-width: 860px){.smxp .contact-grid{grid-template-columns:1fr}}
1038
- .smxp .contact-form{padding:18px}
1039
- .smxp .contact-form h3{margin:0 0 8px;font-size:1.15rem}
1040
- .smxp .contact-form p{margin:0 0 14px}
1041
- .smxp .form-stack{display:grid;gap:10px}
1042
- .smxp .field{display:grid;gap:6px}
1043
- .smxp .field label{font-size:.88rem;font-weight:600;color:var(--fg)}
1044
- .smxp .field input,.smxp .field textarea{
1045
- width:100%;border:1px solid var(--bd);border-radius:14px;padding:12px 13px;
1046
- background:rgba(255,255,255,.72);color:var(--fg);font:inherit;box-sizing:border-box;
1047
- }
1048
- @media (prefers-color-scheme: dark){
1049
- .smxp .field input,.smxp .field textarea{background:rgba(2,6,23,.42);color:var(--fg)}
1050
- }
1051
- .smxp .field textarea{min-height:140px;resize:vertical}
1052
- .smxp .form-actions{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:4px}
1053
- .smxp .form-note{font-size:.88rem;color:var(--mut)}
1054
- .smxp .contact-methods{display:grid;gap:12px}
1055
- .smxp .contact-methods .card h3{font-size:1rem}
1056
- .smxp .pricing-grid .price-card{position:relative}
1057
- .smxp .price-card.featured{transform:translateY(-4px);box-shadow:0 18px 36px rgba(2,6,23,.08)}
1058
- .smxp .price-chip{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--bd);border-radius:999px;padding:5px 10px;font-size:.78rem;margin-bottom:10px}
1059
- .smxp .price-value{font-size:1.9rem;font-weight:800;line-height:1.05;margin:8px 0 2px;color:var(--fg)}
1060
- .smxp .price-suffix{font-size:.9rem;color:var(--mut)}
1061
- .smxp .price-card .btn{margin-top:14px}
1062
-
1063
1043
  </style>
1064
1044
  """.strip()
1065
1045
 
@@ -1559,140 +1539,8 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
1559
1539
  )
1560
1540
 
1561
1541
  continue
1562
-
1563
- # CONTACT
1564
- if stype == "contact":
1565
- form_title = esc(s.get("formTitle") or "Send us a message")
1566
- form_text = esc(s.get("formText") or "Tell us what you need and we will get back to you shortly.")
1567
- submit_label = esc(s.get("submitLabel") or "Send message")
1568
- contact_post_url = f"/contact/{esc(page_slug)}"
1569
-
1570
- detail_cards: List[str] = []
1571
- for it in items:
1572
- if not isinstance(it, dict):
1573
- continue
1574
- it_title = esc(it.get("title") or "Contact")
1575
- it_text = esc_nl(it.get("text") or "")
1576
- ic = icon_svg(it.get("icon") or "")
1577
- raw_html = str(it.get("textHtml") or "").strip()
1578
- if raw_html:
1579
- safe_html = _sanitize_rich_html(raw_html)
1580
- body_html = f'<div class="smx-rich">{safe_html}</div>'
1581
- else:
1582
- body_html = f'<p style="margin-top:8px;">{it_text}</p>'
1583
- detail_cards.append(
1584
- f'''<div class="card reveal">
1585
- <div style="display:flex;gap:10px;align-items:flex-start;">
1586
- {ic}
1587
- <h3 style="margin:0;">{it_title}</h3>
1588
- </div>
1589
- {body_html}
1590
- </div>'''.strip()
1591
- )
1592
-
1593
- details_html = '<div class="contact-methods">' + "\n".join(detail_cards) + '</div>' if detail_cards else ""
1594
-
1595
- parts.append(
1596
- f'''<section id="{esc(sec_dom_id)}" class="sec" data-section-type="contact">
1597
- <div class="wrap">
1598
- <h2 class="reveal">{title}</h2>
1599
- {'<p class="reveal" style="margin-bottom:14px;">'+text+'</p>' if text else ''}
1600
- <div class="contact-grid">
1601
- <div class="card contact-form reveal">
1602
- <h3>{form_title}</h3>
1603
- {f'<p>{form_text}</p>' if form_text else ''}
1604
- <form class="form-stack" method="post" action="{contact_post_url}">
1605
- <input type="hidden" name="contact_anchor" value="{esc(sec_dom_id)}">
1606
- <div class="field">
1607
- <label>Your name</label>
1608
- <input type="text" name="full_name" placeholder="Your name" required>
1609
- </div>
1610
- <div class="field">
1611
- <label>Email address</label>
1612
- <input type="email" name="email" placeholder="you@company.com" required>
1613
- </div>
1614
- <div class="field">
1615
- <label>Phone</label>
1616
- <input type="text" name="phone" placeholder="+353...">
1617
- </div>
1618
- <div class="field">
1619
- <label>Company</label>
1620
- <input type="text" name="company" placeholder="Company name">
1621
- </div>
1622
- <div class="field">
1623
- <label>Message</label>
1624
- <textarea name="message" placeholder="Tell us a little about your enquiry" required></textarea>
1625
- </div>
1626
- <input type="text" name="website" value="" autocomplete="off" style="display:none;">
1627
- <div class="form-actions">
1628
- <button class="btn" type="submit">{submit_label}</button>
1629
- <span class="form-note">We usually reples with practical next steps and the right contact path.</span>
1630
- </div>
1631
- </form>
1632
- </div>
1633
- {details_html}
1634
- </div>
1635
- </div>
1636
- </section>'''.strip()
1637
- )
1638
- continue
1639
-
1640
- # PRICING
1641
- if stype == "pricing":
1642
- try:
1643
- use_cols = int(s.get("cols") or 3)
1644
- except Exception:
1645
- use_cols = 3
1646
- use_cols = max(1, min(4, use_cols))
1647
-
1648
- cards: List[str] = []
1649
- for it in items:
1650
- if not isinstance(it, dict):
1651
- continue
1652
- it_title = esc(it.get("title") or "Plan")
1653
- it_text = esc_nl(it.get("text") or "")
1654
- price = esc(it.get("price") or "")
1655
- price_suffix = esc(it.get("priceSuffix") or "")
1656
- cta_label = esc(it.get("ctaLabel") or "Choose plan")
1657
- cta_href = safe_href(str(it.get("href") or it.get("ctaHref") or "")) or "#sec_cta"
1658
- featured = bool(it.get("featured"))
1659
- raw_html = str(it.get("textHtml") or "").strip()
1660
- if raw_html:
1661
- safe_html = _sanitize_rich_html(raw_html)
1662
- body_html = f'<div class="smx-rich">{safe_html}</div>'
1663
- else:
1664
- body_html = f'<p style="margin-top:10px;">{it_text}</p>'
1665
- cards.append(
1666
- f'''<div class="card reveal price-card{' featured' if featured else ''}" data-item-type="pricing-card">
1667
- {('<div class="price-chip">Most popular</div>' if featured else '')}
1668
- <h3 style="margin:0;">{it_title}</h3>
1669
- {f'<div class="price-value">{price}</div>' if price else ''}
1670
- {f'<div class="price-suffix">{price_suffix}</div>' if price_suffix else ''}
1671
- {body_html}
1672
- <a class="btn" href="{esc(cta_href)}">{cta_label}</a>
1673
- </div>'''.strip()
1674
- )
1675
-
1676
- grid_html = (
1677
- f'<div class="grid pricing-grid" style="grid-template-columns:repeat({use_cols}, minmax(0, 1fr));">'
1678
- + "\n".join(cards) +
1679
- "</div>"
1680
- ) if cards else ""
1681
-
1682
- parts.append(
1683
- f'''<section id="{esc(sec_dom_id)}" class="sec" data-section-type="pricing">
1684
- <div class="wrap">
1685
- <h2 class="reveal">{title}</h2>
1686
- {'<p class="reveal" style="margin-bottom:14px;">'+text+'</p>' if text else ''}
1687
- {grid_html}
1688
- </div>
1689
- </section>'''.strip()
1690
- )
1691
- continue
1692
-
1693
1542
  ####################################################################################################
1694
1543
  # Others
1695
-
1696
1544
  try:
1697
1545
  cols = int(s.get("cols") or 3)
1698
1546
  except Exception:
@@ -1755,28 +1603,6 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
1755
1603
  else:
1756
1604
  body_html = f'<p style="margin-top:8px;{text_align_css}">{it_text}</p>'
1757
1605
 
1758
- cta_href = safe_href(str(it.get("href") or it.get("ctaHref") or ""))
1759
- cta_label = esc((it.get("ctaLabel") or "").strip())
1760
- cta_align = str(it.get("ctaAlign") or "left").strip().lower()
1761
- if cta_align not in {"left", "center", "right", "full"}:
1762
- cta_align = "left"
1763
-
1764
- if cta_href and cta_label:
1765
- wrap_style = {
1766
- "left": "justify-content:flex-start;",
1767
- "center": "justify-content:center;",
1768
- "right": "justify-content:flex-end;",
1769
- "full": "justify-content:stretch;",
1770
- }[cta_align]
1771
- btn_style = "width:100%;justify-content:center;" if cta_align == "full" else ""
1772
- cta_html = (
1773
- f'<div style="display:flex;{wrap_style}margin-top:14px;">'
1774
- f'<a class="btn" href="{esc(cta_href)}" style="{btn_style}">{cta_label}</a>'
1775
- f'</div>'
1776
- )
1777
- else:
1778
- cta_html = ""
1779
-
1780
1606
  tiles.append(
1781
1607
  f'''
1782
1608
  <div class="card reveal" data-item-type="{esc(it_type)}">
@@ -1786,7 +1612,6 @@ def compile_layout_to_html(layout: Dict[str, Any], *, page_slug: str) -> str:
1786
1612
  <h3 style="margin:0;{title_align_css}">{it_title}</h3>
1787
1613
  </div>
1788
1614
  {body_html}
1789
- {cta_html}
1790
1615
  </div>
1791
1616
  '''.strip()
1792
1617
  )
@@ -13,7 +13,7 @@ from bs4 import BeautifulSoup
13
13
  # Config: categories, templates, and allowed section types
14
14
  # ─────────────────────────────────────────────────────────────
15
15
 
16
- KNOWN_CATEGORIES = {"about", "services", "blog", "landing", "contact", "pricing", "docs", "careers"}
16
+ KNOWN_CATEGORIES = {"about", "services", "blog", "landing", "contact", "docs", "careers"}
17
17
 
18
18
  # Template → allowed section types
19
19
  TEMPLATE_ALLOWED_TYPES: Dict[str, set[str]] = {
@@ -26,12 +26,6 @@ TEMPLATE_ALLOWED_TYPES: Dict[str, set[str]] = {
26
26
  "services_detail_v1": {
27
27
  "hero", "offers", "comparison", "process", "case_studies", "faq", "cta"
28
28
  },
29
- "contact_form_v1": {
30
- "hero", "richtext", "contact", "faq", "cta"
31
- },
32
- "pricing_tiers_v1": {
33
- "hero", "richtext", "pricing", "comparison", "faq", "cta"
34
- },
35
29
 
36
30
  # Add more templates later...
37
31
  }
@@ -54,12 +48,6 @@ TEMPLATE_SECTION_ORDER: Dict[str, List[str]] = {
54
48
  "services_detail_v1": [
55
49
  "sec_hero", "sec_offers", "sec_comparison", "sec_process", "sec_case_studies", "sec_faq", "sec_cta"
56
50
  ],
57
- "contact_form_v1": [
58
- "sec_hero", "sec_intro", "sec_contact", "sec_faq", "sec_cta"
59
- ],
60
- "pricing_tiers_v1": [
61
- "sec_hero", "sec_intro", "sec_pricing", "sec_comparison", "sec_faq", "sec_cta"
62
- ],
63
51
 
64
52
  }
65
53
 
@@ -78,15 +66,11 @@ DEFAULT_COLS_BY_TYPE = {
78
66
  "proof": 4,
79
67
  "case_studies": 3,
80
68
  "offers": 2,
81
- "contact": 2,
82
- "pricing": 3,
83
- "richtext": 1,
84
69
  }
85
70
 
86
71
  # “Grid-ish” sections should have .grid in HTML (for your patcher)
87
72
  GRID_SECTION_TYPES = {"values", "team", "logos", "testimonials", "faq", "cta", "features", "gallery",
88
- "richtext", "services", "offers", "comparison", "process", "proof", "case_studies",
89
- "contact", "pricing"
73
+ "richtext", "services", "offers", "comparison", "process", "proof", "case_studies"
90
74
  }
91
75
 
92
76
 
@@ -97,7 +81,7 @@ SECTION_ID_ALIASES = {
97
81
  "top": "sec_hero",
98
82
 
99
83
  "about": "sec_story",
100
- "intro": "sec_intro",
84
+ "intro": "sec_story",
101
85
  "story": "sec_story",
102
86
 
103
87
  "principles": "sec_values",
@@ -118,10 +102,7 @@ SECTION_ID_ALIASES = {
118
102
  "questions": "sec_faq",
119
103
  "faq": "sec_faq",
120
104
 
121
- "contact": "sec_contact",
122
- "contact_form": "sec_contact",
123
- "contact_methods": "sec_contact",
124
- "reach_us": "sec_contact",
105
+ "contact": "sec_cta",
125
106
  "next_steps": "sec_cta",
126
107
  "cta": "sec_cta",
127
108
  "services": "sec_services",
@@ -135,15 +116,13 @@ SECTION_ID_ALIASES = {
135
116
  "cases": "sec_case_studies",
136
117
  "offers": "sec_offers",
137
118
  "comparison": "sec_comparison",
138
- "pricing": "sec_pricing",
139
- "packages": "sec_pricing",
140
- "tiers": "sec_pricing",
119
+ "pricing": "sec_comparison",
120
+ "packages": "sec_offers",
121
+ "tiers": "sec_comparison",
141
122
 
142
123
  }
143
124
 
144
125
  VERSION_RE = re.compile(r"^\d+\.\d+\.\d+$", re.ASCII)
145
- ###########################################
146
-
147
126
  SAFE_ID_RE = re.compile(r"[^a-z0-9_:\-]+", re.ASCII)
148
127
  DANGEROUS_RE = re.compile(
149
128
  r"(<\s*script\b|javascript:|\bon\w+\s*=)", re.IGNORECASE
@@ -0,0 +1,10 @@
1
+ """Premium support.
2
+
3
+ This package contains runtime plumbing for premium features (entitlements +
4
+ plugin loading). The actual premium implementations should live in separate,
5
+ private distributions.
6
+ """
7
+
8
+ from .gate import FeatureGate
9
+
10
+ __all__ = ["FeatureGate"]