ltcai 9.0.0 → 9.1.0

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 (187) hide show
  1. package/README.md +80 -46
  2. package/auto_setup.py +7 -853
  3. package/desktop/electron/README.md +9 -0
  4. package/desktop/electron/main.cjs +5 -3
  5. package/docs/CHANGELOG.md +146 -2
  6. package/docs/COMMUNITY_AND_PLUGINS.md +3 -2
  7. package/docs/DEVELOPMENT.md +53 -14
  8. package/docs/LEGACY_COMPATIBILITY.md +4 -4
  9. package/docs/ONBOARDING.md +10 -2
  10. package/docs/OPERATIONS.md +8 -4
  11. package/docs/PRODUCT_DIRECTION_REVIEW.md +4 -0
  12. package/docs/TRUST_MODEL.md +5 -2
  13. package/docs/WHY_LATTICE.md +15 -10
  14. package/docs/WORKFLOW_DESIGNER.md +22 -0
  15. package/docs/kg-schema.md +13 -2
  16. package/docs/mcp-tools.md +17 -6
  17. package/docs/privacy.md +19 -3
  18. package/docs/public-deploy.md +32 -3
  19. package/docs/security-model.md +46 -11
  20. package/lattice_brain/__init__.py +1 -1
  21. package/lattice_brain/archive.py +1 -6
  22. package/lattice_brain/context.py +66 -9
  23. package/lattice_brain/graph/_kg_fsutil.py +1 -5
  24. package/lattice_brain/graph/discovery_index.py +174 -20
  25. package/lattice_brain/graph/documents.py +44 -9
  26. package/lattice_brain/graph/ingest.py +47 -20
  27. package/lattice_brain/graph/provenance.py +13 -6
  28. package/lattice_brain/graph/retrieval.py +140 -39
  29. package/lattice_brain/graph/retrieval_docgen.py +37 -4
  30. package/lattice_brain/ingestion.py +4 -7
  31. package/lattice_brain/portability.py +28 -14
  32. package/lattice_brain/runtime/agent_runtime.py +5 -9
  33. package/lattice_brain/runtime/hooks.py +30 -13
  34. package/lattice_brain/runtime/multi_agent.py +27 -8
  35. package/lattice_brain/runtime/statuses.py +10 -0
  36. package/lattice_brain/utils.py +20 -2
  37. package/lattice_brain/workflow.py +1 -5
  38. package/latticeai/__init__.py +1 -1
  39. package/latticeai/api/admin.py +1 -1
  40. package/latticeai/api/agent_registry.py +10 -8
  41. package/latticeai/api/agents.py +22 -3
  42. package/latticeai/api/auth.py +78 -16
  43. package/latticeai/api/browser.py +303 -34
  44. package/latticeai/api/chat.py +320 -850
  45. package/latticeai/api/chat_agent_http.py +356 -0
  46. package/latticeai/api/chat_contracts.py +54 -0
  47. package/latticeai/api/chat_documents.py +256 -0
  48. package/latticeai/api/chat_helpers.py +24 -1
  49. package/latticeai/api/chat_history.py +99 -0
  50. package/latticeai/api/chat_intents.py +302 -0
  51. package/latticeai/api/chat_stream.py +115 -0
  52. package/latticeai/api/computer_use.py +62 -9
  53. package/latticeai/api/health.py +9 -3
  54. package/latticeai/api/hooks.py +17 -6
  55. package/latticeai/api/knowledge_graph.py +78 -14
  56. package/latticeai/api/local_files.py +7 -2
  57. package/latticeai/api/mcp.py +102 -23
  58. package/latticeai/api/models.py +72 -33
  59. package/latticeai/api/network.py +5 -5
  60. package/latticeai/api/permissions.py +67 -26
  61. package/latticeai/api/plugins.py +21 -7
  62. package/latticeai/api/portability.py +5 -5
  63. package/latticeai/api/realtime.py +33 -5
  64. package/latticeai/api/setup.py +2 -2
  65. package/latticeai/api/static_routes.py +123 -24
  66. package/latticeai/api/tools.py +96 -14
  67. package/latticeai/api/workflow_designer.py +37 -0
  68. package/latticeai/api/workspace.py +2 -1
  69. package/latticeai/app_factory.py +110 -52
  70. package/latticeai/core/agent.py +19 -9
  71. package/latticeai/core/agent_registry.py +1 -5
  72. package/latticeai/core/config.py +23 -3
  73. package/latticeai/core/context_builder.py +21 -3
  74. package/latticeai/core/invitations.py +1 -4
  75. package/latticeai/core/io_utils.py +9 -1
  76. package/latticeai/core/legacy_compatibility.py +24 -3
  77. package/latticeai/core/marketplace.py +1 -1
  78. package/latticeai/core/plugins.py +15 -0
  79. package/latticeai/core/policy.py +1 -1
  80. package/latticeai/core/realtime.py +38 -15
  81. package/latticeai/core/sessions.py +7 -2
  82. package/latticeai/core/timeutil.py +10 -0
  83. package/latticeai/core/tool_registry.py +90 -18
  84. package/latticeai/core/users.py +1 -5
  85. package/latticeai/core/workspace_graph_trace.py +31 -5
  86. package/latticeai/core/workspace_memory.py +3 -1
  87. package/latticeai/core/workspace_os.py +18 -7
  88. package/latticeai/core/workspace_os_utils.py +0 -5
  89. package/latticeai/core/workspace_permissions.py +2 -1
  90. package/latticeai/core/workspace_plugins.py +1 -1
  91. package/latticeai/core/workspace_runs.py +14 -5
  92. package/latticeai/core/workspace_skills.py +1 -1
  93. package/latticeai/core/workspace_snapshots.py +2 -1
  94. package/latticeai/core/workspace_timeline.py +2 -1
  95. package/latticeai/integrations/telegram_bot.py +94 -43
  96. package/latticeai/models/router.py +130 -36
  97. package/latticeai/runtime/access_runtime.py +62 -4
  98. package/latticeai/runtime/automation_runtime.py +13 -7
  99. package/latticeai/runtime/brain_runtime.py +19 -7
  100. package/latticeai/runtime/chat_wiring.py +2 -0
  101. package/latticeai/runtime/config_runtime.py +58 -26
  102. package/latticeai/runtime/context_runtime.py +16 -4
  103. package/latticeai/runtime/hooks_runtime.py +1 -1
  104. package/latticeai/runtime/model_wiring.py +33 -5
  105. package/latticeai/runtime/namespace_runtime.py +62 -72
  106. package/latticeai/runtime/platform_runtime_wiring.py +4 -3
  107. package/latticeai/runtime/review_wiring.py +1 -1
  108. package/latticeai/runtime/router_registration.py +34 -1
  109. package/latticeai/runtime/security_runtime.py +110 -13
  110. package/latticeai/runtime/stages.py +27 -0
  111. package/latticeai/server_app.py +5 -1
  112. package/latticeai/services/architecture_readiness.py +74 -5
  113. package/latticeai/services/brain_automation.py +3 -26
  114. package/latticeai/services/chat_service.py +205 -15
  115. package/latticeai/services/local_knowledge.py +423 -0
  116. package/latticeai/services/memory_service.py +55 -21
  117. package/latticeai/services/model_engines.py +48 -33
  118. package/latticeai/services/model_errors.py +17 -0
  119. package/latticeai/services/model_loading.py +28 -25
  120. package/latticeai/services/model_runtime.py +228 -162
  121. package/latticeai/services/p_reinforce.py +22 -3
  122. package/latticeai/services/platform_runtime.py +83 -23
  123. package/latticeai/services/product_readiness.py +19 -17
  124. package/latticeai/services/review_queue.py +12 -0
  125. package/latticeai/services/router_context.py +1 -0
  126. package/latticeai/services/run_executor.py +4 -9
  127. package/latticeai/services/search_service.py +203 -28
  128. package/latticeai/services/tool_dispatch.py +28 -5
  129. package/latticeai/services/triggers.py +53 -4
  130. package/latticeai/services/upload_service.py +13 -2
  131. package/latticeai/setup/__init__.py +25 -0
  132. package/latticeai/setup/auto_setup.py +857 -0
  133. package/latticeai/setup/wizard.py +1264 -0
  134. package/latticeai/tools/__init__.py +278 -0
  135. package/{tools → latticeai/tools}/commands.py +67 -7
  136. package/{tools → latticeai/tools}/computer.py +1 -1
  137. package/{tools → latticeai/tools}/documents.py +1 -1
  138. package/{tools → latticeai/tools}/filesystem.py +3 -3
  139. package/latticeai/tools/knowledge.py +178 -0
  140. package/{tools → latticeai/tools}/local_files.py +1 -1
  141. package/{tools → latticeai/tools}/network.py +0 -1
  142. package/local_knowledge_api.py +4 -342
  143. package/package.json +22 -2
  144. package/scripts/brain_quality_eval.py +3 -1
  145. package/scripts/bump_version.py +3 -0
  146. package/scripts/capture_release_evidence.mjs +180 -0
  147. package/scripts/check_current_release_docs.mjs +142 -0
  148. package/scripts/check_i18n_literals.mjs +107 -31
  149. package/scripts/check_openapi_drift.mjs +56 -0
  150. package/scripts/export_openapi.py +67 -7
  151. package/scripts/i18n_literal_allowlist.json +22 -24
  152. package/scripts/run_integration_tests.mjs +72 -10
  153. package/scripts/validate_release_artifacts.py +49 -7
  154. package/scripts/wheel_smoke.py +5 -0
  155. package/setup_wizard.py +3 -1260
  156. package/src-tauri/Cargo.lock +1 -1
  157. package/src-tauri/Cargo.toml +1 -1
  158. package/src-tauri/tauri.conf.json +1 -1
  159. package/static/app/asset-manifest.json +11 -11
  160. package/static/app/assets/Act-Bzz0bUyW.js +1 -0
  161. package/static/app/assets/Brain-Dj2J20YA.js +321 -0
  162. package/static/app/assets/Capture-CqlEl1Ga.js +1 -0
  163. package/static/app/assets/Library-B03FP1Yx.js +1 -0
  164. package/static/app/assets/System-80lHW0Ux.js +1 -0
  165. package/static/app/assets/index-BiMofBTM.js +17 -0
  166. package/static/app/assets/index-Bmx9rzTc.css +2 -0
  167. package/static/app/assets/primitives-Q1A96_7v.js +1 -0
  168. package/static/app/assets/textarea-D13RtnTo.js +1 -0
  169. package/static/app/index.html +2 -2
  170. package/static/sw.js +1 -1
  171. package/tools/__init__.py +21 -269
  172. package/docs/CODE_REVIEW_2026-07-06.md +0 -764
  173. package/latticeai/runtime/app_context_runtime.py +0 -13
  174. package/latticeai/runtime/tail_wiring.py +0 -21
  175. package/scripts/com.pts.claudecode.discord.plist +0 -31
  176. package/scripts/pts-claudecode-discord-bridge.mjs +0 -207
  177. package/scripts/start-pts-claudecode-discord.sh +0 -51
  178. package/static/app/assets/Act-21lIXx2E.js +0 -1
  179. package/static/app/assets/Brain-BqUd5UJJ.js +0 -321
  180. package/static/app/assets/Capture-BA7Z2Q1u.js +0 -1
  181. package/static/app/assets/Library-bFMtyni3.js +0 -1
  182. package/static/app/assets/System-K6krGCqn.js +0 -1
  183. package/static/app/assets/index-C4R3ws30.js +0 -17
  184. package/static/app/assets/index-ChSeOB02.css +0 -2
  185. package/static/app/assets/primitives-sQU3it5I.js +0 -1
  186. package/static/app/assets/textarea-DK3Fd_lR.js +0 -1
  187. package/tools/knowledge.py +0 -95
@@ -21,11 +21,21 @@ from __future__ import annotations
21
21
  import argparse
22
22
  import json
23
23
  import re
24
+ import tarfile
24
25
  import zipfile
25
26
  from pathlib import Path
26
27
  from typing import Dict, List, Optional
27
28
 
28
29
  SEMVER_RE = re.compile(r"^\d+\.\d+\.\d+([.-][0-9A-Za-z.]+)?$")
30
+ FORBIDDEN_PERSONAL_PATHS = (
31
+ re.compile(r"(?:^|/)DISCORD_AGENTS\.md$", re.IGNORECASE),
32
+ re.compile(r"(?:^|/)scripts/[^/]*discord-bridge[^/]*\.mjs$", re.IGNORECASE),
33
+ re.compile(r"(?:^|/)scripts/start-[^/]*-discord\.sh$", re.IGNORECASE),
34
+ re.compile(r"(?:^|/)scripts/com\.[^/]*\.discord\.plist$", re.IGNORECASE),
35
+ re.compile(r"(?:^|/)bin/pts-grok$", re.IGNORECASE),
36
+ re.compile(r"(?:^|/)scripts/launch-pts-grok\.sh$", re.IGNORECASE),
37
+ re.compile(r"(?:^|/)(?:HEARTBEAT|IDENTITY|SOUL|TOOLS|USER)\.md$", re.IGNORECASE),
38
+ )
29
39
 
30
40
 
31
41
  def _expected_names(version: str) -> Dict[str, str]:
@@ -58,6 +68,36 @@ def _vsix_version(path: Path) -> Optional[str]:
58
68
  return None
59
69
 
60
70
 
71
+ def _forbidden_archive_entries(path: Path) -> List[str]:
72
+ """Return machine-local bot/agent paths accidentally shipped in an archive."""
73
+ names: List[str] = []
74
+ try:
75
+ if zipfile.is_zipfile(path):
76
+ with zipfile.ZipFile(path) as archive:
77
+ names = archive.namelist()
78
+ elif tarfile.is_tarfile(path):
79
+ with tarfile.open(path, "r:*") as archive:
80
+ names = archive.getnames()
81
+ except (OSError, tarfile.TarError, zipfile.BadZipFile):
82
+ # Archive integrity is validated by the package-specific smoke checks;
83
+ # this helper is narrowly responsible for preventing personal files.
84
+ return []
85
+
86
+ return sorted(
87
+ name
88
+ for name in names
89
+ if any(pattern.search(name.replace("\\", "/")) for pattern in FORBIDDEN_PERSONAL_PATHS)
90
+ )
91
+
92
+
93
+ def _reject_personal_files(path: Path, artifact_type: str, errors: List[str]) -> None:
94
+ forbidden = _forbidden_archive_entries(path)
95
+ if forbidden:
96
+ errors.append(
97
+ f"{artifact_type} contains machine-local bot/agent files: {', '.join(forbidden)}"
98
+ )
99
+
100
+
61
101
  def validate(
62
102
  version: str,
63
103
  dist_dir: Path,
@@ -84,6 +124,7 @@ def validate(
84
124
  artifact = dist_dir / expected[key]
85
125
  if artifact.is_file():
86
126
  found[key] = str(artifact)
127
+ _reject_personal_files(artifact, key, errors)
87
128
  else:
88
129
  errors.append(f"missing {key}: {artifact.name}")
89
130
 
@@ -91,6 +132,7 @@ def validate(
91
132
  vsix = dist_dir / expected["vsix"]
92
133
  if vsix.is_file():
93
134
  found["vsix"] = str(vsix)
135
+ _reject_personal_files(vsix, "vsix", errors)
94
136
  if not _vsix_has_entrypoint(vsix):
95
137
  errors.append(f"{vsix.name} is missing extension/out/extension.js (compile step skipped?)")
96
138
  vsix_ver = _vsix_version(vsix)
@@ -100,12 +142,12 @@ def validate(
100
142
  errors.append(f"missing vsix: {vsix.name}")
101
143
 
102
144
  # npm pack tarball lives at repo root, not dist/.
103
- if require_tgz:
104
- tgz = dist_dir.parent / f"ltcai-{version}.tgz"
105
- if tgz.is_file():
106
- found["tgz"] = str(tgz)
107
- else:
108
- warnings.append(f"npm tarball not found: {tgz.name} (run `npm pack`)")
145
+ tgz = dist_dir.parent / f"ltcai-{version}.tgz"
146
+ if tgz.is_file():
147
+ found["tgz"] = str(tgz)
148
+ _reject_personal_files(tgz, "npm tarball", errors)
149
+ elif require_tgz:
150
+ errors.append(f"missing npm tarball: {tgz.name} (run `npm pack`)")
109
151
 
110
152
  dmg = dist_dir.parent / "src-tauri" / "target" / "release" / "bundle" / "dmg" / f"Lattice AI_{version}_aarch64.dmg"
111
153
  if dmg.is_file():
@@ -144,7 +186,7 @@ def main(argv: Optional[List[str]] = None) -> int:
144
186
  parser.add_argument("version", help="exact version to validate, e.g. 1.1.0")
145
187
  parser.add_argument("--dist", default="dist", help="dist directory (default: dist)")
146
188
  parser.add_argument("--require-vsix", action="store_true", help="fail if the VSIX is absent")
147
- parser.add_argument("--require-tgz", action="store_true", help="check for npm pack tarball at repo root")
189
+ parser.add_argument("--require-tgz", action="store_true", help="fail if the npm pack tarball is absent")
148
190
  parser.add_argument("--require-dmg", action="store_true", help="fail if the Tauri DMG is absent")
149
191
  parser.add_argument("--json", action="store_true", help="emit machine-readable JSON")
150
192
  args = parser.parse_args(argv)
@@ -53,6 +53,8 @@ WHEEL_MODULES = [
53
53
  "latticeai.core.mcp_registry",
54
54
  "latticeai.api.knowledge_graph",
55
55
  "latticeai.services.p_reinforce",
56
+ "latticeai.tools",
57
+ "latticeai.tools.knowledge",
56
58
  "ltcai_cli",
57
59
  "auto_setup",
58
60
  "server",
@@ -65,11 +67,14 @@ WHEEL_MODULES = [
65
67
  "p_reinforce",
66
68
  "telegram_bot",
67
69
  "tools",
70
+ "tools.knowledge",
68
71
  ]
69
72
 
70
73
  IMPORT_CHECK = (
71
74
  "import importlib\n"
72
75
  + "".join(f"importlib.import_module({mod!r})\n" for mod in WHEEL_MODULES)
76
+ + "assert importlib.import_module('tools') is importlib.import_module('latticeai.tools')\n"
77
+ + "assert importlib.import_module('tools.knowledge') is importlib.import_module('latticeai.tools.knowledge')\n"
73
78
  + f"print('wheel imports ok: {len(WHEEL_MODULES)} modules')\n"
74
79
  )
75
80