ltcai 10.0.0 → 10.2.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 (211) hide show
  1. package/README.md +48 -32
  2. package/docs/CHANGELOG.md +156 -0
  3. package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
  4. package/docs/DEVELOPMENT.md +1 -1
  5. package/docs/HYBRID_CLOUD_KG_STREAMING.md +101 -0
  6. package/docs/ONBOARDING.md +1 -1
  7. package/docs/OPERATIONS.md +1 -1
  8. package/docs/TRUST_MODEL.md +1 -1
  9. package/docs/WHY_LATTICE.md +1 -1
  10. package/docs/kg-schema.md +1 -1
  11. package/lattice_brain/__init__.py +1 -1
  12. package/lattice_brain/archive.py +5 -4
  13. package/lattice_brain/conversations.py +14 -3
  14. package/lattice_brain/embeddings.py +12 -2
  15. package/lattice_brain/graph/_kg_common.py +5 -5
  16. package/lattice_brain/graph/_kg_fsutil.py +4 -3
  17. package/lattice_brain/graph/discovery.py +4 -3
  18. package/lattice_brain/graph/discovery_index.py +0 -1
  19. package/lattice_brain/graph/documents.py +3 -2
  20. package/lattice_brain/graph/fusion.py +4 -0
  21. package/lattice_brain/graph/ingest.py +12 -2
  22. package/lattice_brain/graph/projection.py +3 -2
  23. package/lattice_brain/graph/provenance.py +5 -3
  24. package/lattice_brain/graph/rerank.py +4 -1
  25. package/lattice_brain/graph/retrieval.py +0 -1
  26. package/lattice_brain/graph/retrieval_docgen.py +0 -1
  27. package/lattice_brain/graph/retrieval_reads.py +0 -1
  28. package/lattice_brain/graph/retrieval_vector.py +0 -1
  29. package/lattice_brain/graph/schema.py +4 -3
  30. package/lattice_brain/graph/store.py +18 -4
  31. package/lattice_brain/graph/write_master.py +46 -1
  32. package/lattice_brain/ingestion.py +4 -1
  33. package/lattice_brain/portability.py +5 -2
  34. package/lattice_brain/quality.py +12 -5
  35. package/lattice_brain/quiet.py +43 -0
  36. package/lattice_brain/runtime/agent_runtime.py +12 -8
  37. package/lattice_brain/runtime/hooks.py +2 -1
  38. package/lattice_brain/runtime/multi_agent.py +2 -3
  39. package/lattice_brain/sensitivity.py +94 -0
  40. package/lattice_brain/storage/base.py +30 -2
  41. package/lattice_brain/storage/migration.py +3 -2
  42. package/lattice_brain/storage/postgres.py +2 -2
  43. package/lattice_brain/storage/sqlite.py +6 -4
  44. package/lattice_brain/workflow.py +4 -2
  45. package/latticeai/__init__.py +1 -1
  46. package/latticeai/api/admin.py +1 -1
  47. package/latticeai/api/agents.py +4 -2
  48. package/latticeai/api/auth.py +5 -1
  49. package/latticeai/api/automation_intelligence.py +2 -1
  50. package/latticeai/api/browser.py +3 -2
  51. package/latticeai/api/chat.py +28 -17
  52. package/latticeai/api/chat_agent_http.py +22 -8
  53. package/latticeai/api/chat_contracts.py +4 -0
  54. package/latticeai/api/chat_documents.py +6 -2
  55. package/latticeai/api/chat_hybrid.py +82 -0
  56. package/latticeai/api/computer_use.py +8 -3
  57. package/latticeai/api/knowledge_graph.py +1 -1
  58. package/latticeai/api/mcp.py +4 -4
  59. package/latticeai/api/models.py +5 -2
  60. package/latticeai/api/network_boundary.py +220 -0
  61. package/latticeai/api/permissions.py +0 -1
  62. package/latticeai/api/realtime.py +1 -1
  63. package/latticeai/api/security_dashboard.py +1 -1
  64. package/latticeai/api/setup.py +16 -3
  65. package/latticeai/api/static_routes.py +2 -1
  66. package/latticeai/api/tools.py +12 -8
  67. package/latticeai/api/voice_capture.py +3 -1
  68. package/latticeai/api/workflow_designer.py +1 -1
  69. package/latticeai/api/workspace.py +1 -2
  70. package/latticeai/app_factory.py +131 -78
  71. package/latticeai/cli/entrypoint.py +6 -4
  72. package/latticeai/core/agent.py +55 -495
  73. package/latticeai/core/agent_eval.py +2 -2
  74. package/latticeai/core/agent_helpers.py +493 -0
  75. package/latticeai/core/agent_prompts.py +0 -1
  76. package/latticeai/core/agent_registry.py +3 -1
  77. package/latticeai/core/agent_state.py +41 -0
  78. package/latticeai/core/audit.py +1 -1
  79. package/latticeai/core/builtin_hooks.py +2 -1
  80. package/latticeai/core/config.py +0 -1
  81. package/latticeai/core/embedding_providers.py +12 -1
  82. package/latticeai/core/file_generation.py +3 -0
  83. package/latticeai/core/invitations.py +4 -1
  84. package/latticeai/core/io_utils.py +3 -1
  85. package/latticeai/core/legacy_compatibility.py +1 -2
  86. package/latticeai/core/local_embeddings.py +12 -1
  87. package/latticeai/core/marketplace.py +1 -2
  88. package/latticeai/core/mcp_registry.py +0 -1
  89. package/latticeai/core/model_compat.py +1 -1
  90. package/latticeai/core/model_resolution.py +1 -1
  91. package/latticeai/core/network_boundary.py +168 -0
  92. package/latticeai/core/oidc.py +3 -0
  93. package/latticeai/core/permission_mode.py +6 -6
  94. package/latticeai/core/plugins.py +3 -2
  95. package/latticeai/core/policy.py +0 -1
  96. package/latticeai/core/quiet.py +84 -0
  97. package/latticeai/core/realtime.py +3 -2
  98. package/latticeai/core/run_store.py +4 -2
  99. package/latticeai/core/security.py +4 -0
  100. package/latticeai/core/users.py +5 -3
  101. package/latticeai/core/workspace_graph_trace.py +3 -0
  102. package/latticeai/core/workspace_os.py +65 -273
  103. package/latticeai/core/workspace_os_constants.py +126 -0
  104. package/latticeai/core/workspace_os_state.py +180 -0
  105. package/latticeai/core/workspace_os_utils.py +3 -1
  106. package/latticeai/core/workspace_permissions.py +1 -0
  107. package/latticeai/core/workspace_snapshots.py +3 -1
  108. package/latticeai/core/workspace_timeline.py +3 -1
  109. package/latticeai/integrations/telegram_bot.py +25 -16
  110. package/latticeai/models/router.py +6 -3
  111. package/latticeai/runtime/access_runtime.py +3 -1
  112. package/latticeai/runtime/audit_runtime.py +3 -2
  113. package/latticeai/runtime/chat_wiring.py +4 -1
  114. package/latticeai/runtime/history_runtime.py +1 -1
  115. package/latticeai/runtime/lifespan_runtime.py +3 -1
  116. package/latticeai/runtime/network_boundary_wiring.py +124 -0
  117. package/latticeai/runtime/persistence_runtime.py +3 -1
  118. package/latticeai/runtime/router_registration.py +11 -1
  119. package/latticeai/services/architecture_readiness.py +1 -2
  120. package/latticeai/services/change_proposals.py +2 -1
  121. package/latticeai/services/cloud_egress_audit.py +85 -0
  122. package/latticeai/services/cloud_extraction.py +129 -0
  123. package/latticeai/services/cloud_streaming.py +266 -0
  124. package/latticeai/services/cloud_token_guard.py +84 -0
  125. package/latticeai/services/command_center.py +2 -1
  126. package/latticeai/services/folder_watch.py +3 -0
  127. package/latticeai/services/funnel_metrics.py +3 -1
  128. package/latticeai/services/hybrid_chat.py +265 -0
  129. package/latticeai/services/hybrid_context.py +228 -0
  130. package/latticeai/services/hybrid_policy.py +178 -0
  131. package/latticeai/services/memory_service.py +1 -1
  132. package/latticeai/services/model_catalog.py +10 -1
  133. package/latticeai/services/model_engines.py +35 -14
  134. package/latticeai/services/model_loading.py +3 -2
  135. package/latticeai/services/model_runtime.py +68 -17
  136. package/latticeai/services/multimodal_streaming.py +123 -0
  137. package/latticeai/services/network_boundary_service.py +154 -0
  138. package/latticeai/services/openai_compatible_adapter.py +100 -0
  139. package/latticeai/services/p_reinforce.py +4 -0
  140. package/latticeai/services/platform_runtime.py +9 -4
  141. package/latticeai/services/process_audit.py +0 -1
  142. package/latticeai/services/product_readiness.py +1 -1
  143. package/latticeai/services/run_executor.py +3 -2
  144. package/latticeai/services/search_service.py +1 -4
  145. package/latticeai/services/setup_detection.py +2 -1
  146. package/latticeai/services/tool_dispatch.py +7 -2
  147. package/latticeai/services/upload_service.py +2 -1
  148. package/latticeai/setup/auto_setup.py +10 -7
  149. package/latticeai/setup/wizard.py +15 -11
  150. package/latticeai/tools/__init__.py +3 -3
  151. package/latticeai/tools/commands.py +7 -7
  152. package/latticeai/tools/computer.py +3 -2
  153. package/latticeai/tools/documents.py +10 -9
  154. package/latticeai/tools/filesystem.py +7 -4
  155. package/latticeai/tools/knowledge.py +2 -0
  156. package/latticeai/tools/local_files.py +1 -1
  157. package/latticeai/tools/network.py +2 -1
  158. package/package.json +5 -3
  159. package/scripts/bench_agent_smoke.py +0 -1
  160. package/scripts/bench_models.py +0 -1
  161. package/scripts/brain_quality_eval.py +7 -2
  162. package/scripts/bump_version.py +2 -1
  163. package/scripts/check_current_release_docs.mjs +1 -1
  164. package/scripts/migrate_brain_storage.py +5 -1
  165. package/scripts/profile_kg.py +2 -7
  166. package/scripts/verify_hf_model_registry.py +2 -2
  167. package/src-tauri/Cargo.lock +1 -1
  168. package/src-tauri/Cargo.toml +1 -1
  169. package/src-tauri/tauri.conf.json +1 -1
  170. package/static/app/asset-manifest.json +37 -37
  171. package/static/app/assets/{Act-BtCREeN1.js → Act-CbdGD-2i.js} +1 -1
  172. package/static/app/assets/{AdminConsole-TPeeN18T.js → AdminConsole-LgCkXpnf.js} +1 -1
  173. package/static/app/assets/{Brain-BKs6JAp0.js → Brain-CoPGJI1L.js} +1 -1
  174. package/static/app/assets/{BrainHome-BPGOvSd6.js → BrainHome-gVnaxSwp.js} +1 -1
  175. package/static/app/assets/{BrainSignals-CtzQZ15J.js → BrainSignals-ChxAYHtj.js} +1 -1
  176. package/static/app/assets/{Capture-1_NaHWqB.js → Capture-DBtgkHZg.js} +1 -1
  177. package/static/app/assets/{CommandPalette-pqvQOXe4.js → CommandPalette-Ovtv5I0Y.js} +1 -1
  178. package/static/app/assets/{Library-DhvoPvC7.js → Library-CBia2Fvm.js} +1 -1
  179. package/static/app/assets/{LivingBrain-DlQ20Q75.js → LivingBrain-CNz-6NSd.js} +1 -1
  180. package/static/app/assets/{ProductFlow-BZvGDRi_.js → ProductFlow-ePX-Y73J.js} +1 -1
  181. package/static/app/assets/{ReviewCard-BWgI0D2s.js → ReviewCard-C4mpvkwH.js} +1 -1
  182. package/static/app/assets/System-BvWNK1zc.js +1 -0
  183. package/static/app/assets/{activity-Dlfk8YC7.js → activity-CiauPV_3.js} +1 -1
  184. package/static/app/assets/{bot-CDvUB76P.js → bot-Dwct-Q1x.js} +1 -1
  185. package/static/app/assets/{brain-xczrohrt.js → brain-BKDW1F0T.js} +1 -1
  186. package/static/app/assets/{button-SOdH3Oyf.js → button-CCB9Kuw7.js} +1 -1
  187. package/static/app/assets/{circle-pause-CG1ythH4.js → circle-pause-DNa8WHC5.js} +1 -1
  188. package/static/app/assets/{circle-play-HXwvjS6W.js → circle-play-8jmxn5mf.js} +1 -1
  189. package/static/app/assets/{cpu-B0d-rGyk.js → cpu-mxvF3V1I.js} +1 -1
  190. package/static/app/assets/{download-BGIkTQL6.js → download--SmCcx0p.js} +1 -1
  191. package/static/app/assets/{folder-open-Dst_Z0_K.js → folder-open-D4Wy5roo.js} +1 -1
  192. package/static/app/assets/{hard-drive-D53MsWkV.js → hard-drive-BwQcSPlS.js} +1 -1
  193. package/static/app/assets/index-CQWdDU3z.css +2 -0
  194. package/static/app/assets/{index-C_IrlQMV.js → index-DDV2YZwM.js} +3 -3
  195. package/static/app/assets/{input-C5m0riF6.js → input-DFhSjmLS.js} +1 -1
  196. package/static/app/assets/{network-C5a-E5iS.js → network-Bts7VO94.js} +1 -1
  197. package/static/app/assets/{primitives-vNXYf58F.js → primitives-BuSMEJY8.js} +1 -1
  198. package/static/app/assets/search-DZzxhWaQ.js +1 -0
  199. package/static/app/assets/{shield-alert-Cc-WVXqN.js → shield-alert-BfTO6X_G.js} +1 -1
  200. package/static/app/assets/{textarea-BkZ0EqVO.js → textarea-BjctW1oh.js} +1 -1
  201. package/static/app/assets/{useFocusTrap-CTtKbAOU.js → useFocusTrap-CE43-LrA.js} +1 -1
  202. package/static/app/assets/{useQuery-Dx1fi4Wu.js → useQuery-Bv3ejLL5.js} +1 -1
  203. package/static/app/assets/{users-BFpQXtEF.js → users-CsNqLZAj.js} +1 -1
  204. package/static/app/assets/{utils-BA_lmW3J.js → utils-KFFdVG_t.js} +2 -2
  205. package/static/app/assets/workspace-wdCvdyPF.js +1 -0
  206. package/static/app/index.html +4 -4
  207. package/static/sw.js +1 -1
  208. package/static/app/assets/System-CSMdYLMy.js +0 -1
  209. package/static/app/assets/index-FxDusbr0.css +0 -2
  210. package/static/app/assets/search-DhbSgW6m.js +0 -1
  211. package/static/app/assets/workspace-DBPB0jkX.js +0 -1
@@ -17,6 +17,8 @@ from datetime import datetime
17
17
  from pathlib import Path
18
18
  from typing import Any, Optional
19
19
 
20
+ from latticeai.core.quiet import quiet
21
+
20
22
  BRAIN_DIR = Path(
21
23
  os.getenv("LATTICEAI_OBSIDIAN_VAULT_DIR")
22
24
  or os.getenv("LATTICEAI_BRAIN_DIR")
@@ -213,6 +215,7 @@ class PReinforceGardener:
213
215
  "modified_at": datetime.fromtimestamp(stat.st_mtime).isoformat(timespec="seconds"),
214
216
  })
215
217
  except OSError:
218
+ quiet()
216
219
  continue
217
220
  folders.append({"name": folder, "description": desc, "files": files, "count": len(files)})
218
221
  return {"root": str(BRAIN_DIR), "folders": folders}
@@ -273,5 +276,6 @@ class PReinforceGardener:
273
276
  if len(results) >= limit:
274
277
  break
275
278
  except Exception:
279
+ quiet()
276
280
  continue
277
281
  return "\n\n".join(results)
@@ -18,8 +18,13 @@ from typing import Any, Callable, Dict, Optional, Set
18
18
  from fastapi import HTTPException, Request
19
19
 
20
20
  from lattice_brain.runtime.hooks import dispatch_tool
21
- from lattice_brain.runtime.multi_agent import MultiAgentOrchestrator, default_role_runner, llm_role_runner
21
+ from lattice_brain.runtime.multi_agent import (
22
+ MultiAgentOrchestrator,
23
+ default_role_runner,
24
+ llm_role_runner,
25
+ )
22
26
  from lattice_brain.workflow import ApprovalRequired, WorkflowEngine
27
+ from latticeai.core.quiet import quiet
23
28
  from latticeai.core.tool_registry import SCOPED_KNOWLEDGE_TOOLS
24
29
  from latticeai.services.tool_dispatch import enforce_tool_policy
25
30
  from latticeai.tools import execute_tool
@@ -178,7 +183,7 @@ class PlatformRuntime:
178
183
  except Exception:
179
184
  # Recall is an enrichment seam; the legacy store fallback
180
185
  # keeps agent execution available if it degrades.
181
- pass
186
+ quiet()
182
187
  try:
183
188
  mems = self.store.search_memories(goal, user_email=user, workspace_id=scope).get("memories", [])
184
189
  ctx = [str(m.get("content") or "")[:180] for m in mems[:6]]
@@ -188,7 +193,7 @@ class PlatformRuntime:
188
193
  synth = [str(m.get("content") or "")[:160] for m in allm if "agent-synthesis" in (m.get("tags") or [])][:3]
189
194
  ctx = synth + ctx
190
195
  except Exception:
191
- pass
196
+ quiet()
192
197
  if not ctx:
193
198
  try:
194
199
  recent = self.store.list_memories(user_email=user, workspace_id=scope).get("memories", [])
@@ -196,7 +201,7 @@ class PlatformRuntime:
196
201
  # itself in the knowledge that just entered the Brain.
197
202
  ctx = [str(m.get("content") or "")[:180] for m in recent[:8]]
198
203
  except Exception:
199
- pass
204
+ quiet()
200
205
  return ctx[:8]
201
206
  except Exception:
202
207
  return []
@@ -10,7 +10,6 @@ import time
10
10
  from pathlib import Path
11
11
  from typing import Any, Iterable, Mapping, Optional, Sequence
12
12
 
13
-
14
13
  _SECRET_RE = re.compile(
15
14
  r"(api[_-]?key|access[_-]?token|auth[_-]?token|bearer|client[_-]?secret|password|secret|token)",
16
15
  re.IGNORECASE,
@@ -18,7 +18,7 @@ from typing import Any, Dict, List
18
18
 
19
19
  from latticeai.services.architecture_readiness import architecture_readiness
20
20
 
21
- PRODUCT_VERSION_TARGET = "10.0.0"
21
+ PRODUCT_VERSION_TARGET = "10.2.0"
22
22
 
23
23
 
24
24
  @dataclass(frozen=True)
@@ -16,6 +16,7 @@ from lattice_brain.runtime.statuses import (
16
16
  RUN_ACTIVE_STATUSES as ACTIVE_STATUSES,
17
17
  )
18
18
  from lattice_brain.workflow import WorkflowEngine
19
+ from latticeai.core.quiet import quiet
19
20
  from latticeai.core.timeutil import now_iso as _now
20
21
 
21
22
 
@@ -144,7 +145,7 @@ class RunExecutor:
144
145
  try:
145
146
  self.append_audit_event("agent_run_failed", user_email=user_email, run_id=run_id, error=str(exc))
146
147
  except Exception:
147
- pass
148
+ quiet()
148
149
  finally:
149
150
  self._handles.pop(run_id, None)
150
151
 
@@ -299,7 +300,7 @@ class RunExecutor:
299
300
  workspace_id=workspace_id,
300
301
  )
301
302
  except Exception:
302
- pass
303
+ quiet()
303
304
 
304
305
  def _execute_workflow_sync(
305
306
  self,
@@ -13,7 +13,6 @@ from typing import Any, Dict, List, Mapping, Optional
13
13
  from lattice_brain.graph._kg_fsutil import _parse_iso, _recency_score
14
14
  from lattice_brain.graph.retrieval_policy import resolve_policy
15
15
 
16
-
17
16
  DEFAULT_HYBRID_WEIGHTS = {
18
17
  "keyword": 0.35,
19
18
  "vector": 0.40,
@@ -70,9 +69,7 @@ class SearchService:
70
69
  if not node_id or node_id not in scopes:
71
70
  continue
72
71
  scope = scopes[node_id]
73
- if scope is None and include_legacy_global:
74
- visible.append(item)
75
- elif scope is not None and str(scope) in allowed:
72
+ if scope is None and include_legacy_global or scope is not None and str(scope) in allowed:
76
73
  visible.append(item)
77
74
  return visible
78
75
 
@@ -6,6 +6,7 @@ import json
6
6
  import re
7
7
  from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
8
8
 
9
+ from latticeai.core.quiet import quiet
9
10
 
10
11
  WhichFn = Callable[[str], Optional[str]]
11
12
  RunFn = Callable[[List[str]], str]
@@ -32,7 +33,7 @@ def parse_windows_video_controllers(raw: str) -> List[Dict[str, Any]]:
32
33
  if controllers:
33
34
  return controllers
34
35
  except Exception:
35
- pass
36
+ quiet()
36
37
  current: Dict[str, Any] = {}
37
38
  for line in raw.splitlines():
38
39
  if line.startswith("Name="):
@@ -6,9 +6,9 @@ tool-response shaping are owned outside ``server_app``.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import subprocess
9
10
  from dataclasses import dataclass, field
10
11
  from pathlib import Path
11
- import subprocess
12
12
  from typing import Any, Callable, Dict, Mapping, Optional
13
13
 
14
14
  from fastapi import HTTPException
@@ -30,7 +30,12 @@ from latticeai.core.permission_mode import (
30
30
  from latticeai.core.policy import role_has_capability
31
31
  from latticeai.core.tool_governor import classify_tool_call
32
32
  from latticeai.core.tool_registry import ToolPermission, ToolPolicy
33
- from latticeai.tools import AGENT_ROOT, DEFAULT_TOOL_REGISTRY, ToolError, ensure_agent_root
33
+ from latticeai.tools import (
34
+ AGENT_ROOT,
35
+ DEFAULT_TOOL_REGISTRY,
36
+ ToolError,
37
+ ensure_agent_root,
38
+ )
34
39
 
35
40
 
36
41
  def _default_load_users() -> Dict[str, Any]:
@@ -11,6 +11,7 @@ from typing import Optional
11
11
  from fastapi import HTTPException, Request, UploadFile
12
12
 
13
13
  from lattice_brain.ingestion import IngestionItem
14
+ from latticeai.core.quiet import quiet
14
15
  from latticeai.tools import ToolError, read_document
15
16
 
16
17
 
@@ -161,7 +162,7 @@ async def process_uploaded_document(
161
162
  try:
162
163
  Path(tmp_path).unlink()
163
164
  except OSError:
164
- pass
165
+ quiet()
165
166
 
166
167
  # ── post_upload hook ── the whole upload → parse → index pipeline finished.
167
168
  if hooks is not None:
@@ -47,6 +47,7 @@ from dataclasses import asdict, dataclass, field
47
47
  from pathlib import Path
48
48
  from typing import Any, Dict, List, Optional, Tuple
49
49
 
50
+ from latticeai.core.quiet import quiet
50
51
  from latticeai.services.process_audit import (
51
52
  CommandConfirmationError,
52
53
  append_process_audit_event,
@@ -58,6 +59,8 @@ from latticeai.services.setup_detection import (
58
59
  detect_cuda,
59
60
  detect_tools,
60
61
  detect_wsl_from_text,
62
+ )
63
+ from latticeai.services.setup_detection import (
61
64
  parse_windows_video_controllers as _parse_windows_video_controllers,
62
65
  )
63
66
 
@@ -177,7 +180,7 @@ def _detect_gpu(prof_os: str, arch: str) -> GPUInfo:
177
180
  gpu.vram_mb = int(float(mem))
178
181
  gpu.sdk.append("cuda")
179
182
  except ValueError:
180
- pass
183
+ quiet()
181
184
 
182
185
  # Apple Silicon / Metal
183
186
  if prof_os == "darwin":
@@ -268,7 +271,7 @@ def _detect_cpu_details(prof_os: str) -> Tuple[str, int, int, List[str]]:
268
271
  physical = int((_run(["sysctl", "-n", "hw.physicalcpu"]).strip() or physical))
269
272
  logical = int((_run(["sysctl", "-n", "hw.logicalcpu"]).strip() or logical))
270
273
  except ValueError:
271
- pass
274
+ quiet()
272
275
  flags = [item.lower() for item in _run(["sysctl", "-n", "machdep.cpu.features"]).split()]
273
276
  elif prof_os == "linux":
274
277
  text = _read_text("/proc/cpuinfo")
@@ -287,19 +290,19 @@ def _detect_cpu_details(prof_os: str) -> Tuple[str, int, int, List[str]]:
287
290
  try:
288
291
  physical = int(value.strip())
289
292
  except ValueError:
290
- pass
293
+ quiet()
291
294
  elif key == "NumberOfLogicalProcessors" and value.strip():
292
295
  try:
293
296
  logical = int(value.strip())
294
297
  except ValueError:
295
- pass
298
+ quiet()
296
299
  try:
297
300
  import ctypes
298
301
  kernel32 = ctypes.windll.kernel32
299
302
  feature_map = {6: "sse", 10: "sse2", 13: "sse3", 19: "neon", 28: "rdrand"}
300
303
  flags.extend(name for code, name in feature_map.items() if kernel32.IsProcessorFeaturePresent(code))
301
304
  except Exception:
302
- pass
305
+ quiet()
303
306
  interesting = {"avx", "avx2", "avx512f", "fma", "neon", "sse4_2", "sse", "sse2", "sse3", "rdrand"}
304
307
  return model, physical, logical, sorted({flag for flag in flags if flag in interesting})
305
308
 
@@ -368,14 +371,14 @@ def probe() -> SystemProfile:
368
371
  prof.ram_mb = int(line.split("=", 1)[-1].strip()) // (1024 * 1024)
369
372
  break
370
373
  except Exception:
371
- pass
374
+ quiet()
372
375
 
373
376
  # Disk
374
377
  try:
375
378
  usage = shutil.disk_usage(Path.home())
376
379
  prof.disk_free_mb = usage.free // (1024 * 1024)
377
380
  except Exception:
378
- pass
381
+ quiet()
379
382
 
380
383
  prof.gpu = _detect_gpu(prof.os, prof.arch)
381
384
  prof.package_manager = _detect_package_manager(prof.os)
@@ -21,6 +21,7 @@ import time
21
21
  from pathlib import Path
22
22
  from typing import Any, AsyncIterator, Dict, List, Tuple
23
23
 
24
+ from latticeai.core.quiet import quiet
24
25
  from latticeai.services.process_audit import (
25
26
  CommandConfirmationError,
26
27
  append_process_audit_event,
@@ -32,6 +33,8 @@ from latticeai.services.setup_detection import (
32
33
  detect_cuda,
33
34
  detect_tools,
34
35
  detect_wsl_from_text,
36
+ )
37
+ from latticeai.services.setup_detection import (
35
38
  parse_windows_video_controllers as _parse_windows_video_controllers,
36
39
  )
37
40
 
@@ -304,7 +307,7 @@ def _detect_chip() -> Dict[str, Any]:
304
307
  brand = line.split(":", 1)[-1].strip()
305
308
  break
306
309
  except Exception:
307
- pass
310
+ quiet()
308
311
  name = brand or platform.processor() or "Unknown CPU"
309
312
 
310
313
  return {"name": name, "arch": arch, "is_apple_silicon": is_apple, "gen": gen}
@@ -321,7 +324,7 @@ def _detect_cpu() -> Dict[str, Any]:
321
324
  physical_cores = int(_cmd(["sysctl", "-n", "hw.physicalcpu"], timeout=5) or physical_cores)
322
325
  logical_cores = int(_cmd(["sysctl", "-n", "hw.logicalcpu"], timeout=5) or logical_cores)
323
326
  except ValueError:
324
- pass
327
+ quiet()
325
328
  elif platform.system() == "Linux":
326
329
  try:
327
330
  text = Path("/proc/cpuinfo").read_text(encoding="utf-8", errors="replace")
@@ -330,7 +333,7 @@ def _detect_cpu() -> Dict[str, Any]:
330
333
  flags = line.split(":", 1)[-1].strip().lower().split()
331
334
  break
332
335
  except Exception:
333
- pass
336
+ quiet()
334
337
  elif platform.system() == "Windows":
335
338
  raw = _cmd(["wmic", "cpu", "get", "Name,NumberOfCores,NumberOfLogicalProcessors", "/format:list"], timeout=5)
336
339
  for line in raw.splitlines():
@@ -341,12 +344,12 @@ def _detect_cpu() -> Dict[str, Any]:
341
344
  try:
342
345
  physical_cores = int(value.strip())
343
346
  except ValueError:
344
- pass
347
+ quiet()
345
348
  elif key == "NumberOfLogicalProcessors" and value.strip():
346
349
  try:
347
350
  logical_cores = int(value.strip())
348
351
  except ValueError:
349
- pass
352
+ quiet()
350
353
  try:
351
354
  import ctypes
352
355
  kernel32 = ctypes.windll.kernel32
@@ -359,7 +362,7 @@ def _detect_cpu() -> Dict[str, Any]:
359
362
  }
360
363
  flags.extend(name for code, name in feature_map.items() if kernel32.IsProcessorFeaturePresent(code))
361
364
  except Exception:
362
- pass
365
+ quiet()
363
366
  interesting = {"avx", "avx2", "avx512f", "fma", "neon", "sse4_2"}
364
367
  if platform.system() == "Windows":
365
368
  interesting.update({"sse", "sse2", "sse3", "rdrand"})
@@ -384,7 +387,7 @@ def _detect_ram_gb() -> float:
384
387
  try:
385
388
  return round(int(raw) / 1_073_741_824, 1)
386
389
  except ValueError:
387
- pass
390
+ quiet()
388
391
  if platform.system() == "Darwin":
389
392
  profiler = _cmd(["system_profiler", "SPHardwareDataType"], timeout=8)
390
393
  m = re.search(r"Memory:\s+([\d.]+)\s*(TB|GB|MB)", profiler, re.IGNORECASE)
@@ -406,7 +409,7 @@ def _detect_ram_gb() -> float:
406
409
  if line.startswith("MemTotal:"):
407
410
  return round(int(line.split()[1]) / 1_048_576, 1)
408
411
  except Exception:
409
- pass
412
+ quiet()
410
413
  return 0.0
411
414
 
412
415
  def _detect_disk_free_gb() -> float:
@@ -427,6 +430,7 @@ def _detect_gpu() -> Dict[str, Any]:
427
430
  name, mem = [part.strip() for part in line.split(",", 1)]
428
431
  devices.append({"vendor": "nvidia", "name": name, "vram_mb": int(float(mem)), "backend": "cuda"})
429
432
  except Exception:
433
+ quiet()
430
434
  continue
431
435
 
432
436
  if platform.system() == "Windows":
@@ -492,7 +496,7 @@ def _detect_wsl() -> Dict[str, Any]:
492
496
  try:
493
497
  raw = Path("/proc/version").read_text(encoding="utf-8", errors="replace")
494
498
  except Exception:
495
- pass
499
+ quiet()
496
500
  is_wsl, version = detect_wsl_from_text(platform.system().lower(), raw)
497
501
  return {"is_wsl": is_wsl, "version": version}
498
502
 
@@ -1243,7 +1247,7 @@ def open_url(url: str) -> None:
1243
1247
  command = ["os.startfile", url]
1244
1248
  plan = command_plan(command, name="open_url", purpose="setup_wizard_open_url")
1245
1249
  append_process_audit_event("setup_wizard_open_url", plan=plan, status="started")
1246
- os.startfile(url) # type: ignore[attr-defined]
1250
+ os.startfile(url) # type: ignore[attr-defined] # noqa: S606 — fixed program, arguments validated by the caller
1247
1251
  append_process_audit_event("setup_wizard_open_url", plan=plan, status="spawned")
1248
1252
  else:
1249
1253
  command = ["xdg-open", url]
@@ -1260,5 +1264,5 @@ def open_url(url: str) -> None:
1260
1264
  error=str(exc),
1261
1265
  )
1262
1266
  except Exception:
1263
- pass
1267
+ quiet()
1264
1268
  pass
@@ -152,13 +152,13 @@ DOCUMENT_MAX_READ_BYTES = 10_000_000 # 10 MB
152
152
 
153
153
 
154
154
  # ── focused tool submodules (re-exported flat for import compatibility) ───────
155
+ from latticeai.tools.commands import * # noqa: E402,F401,F403
155
156
  from latticeai.tools.computer import * # noqa: E402,F401,F403
156
- from latticeai.tools.filesystem import * # noqa: E402,F401,F403
157
157
  from latticeai.tools.documents import * # noqa: E402,F401,F403
158
- from latticeai.tools.local_files import * # noqa: E402,F401,F403
158
+ from latticeai.tools.filesystem import * # noqa: E402,F401,F403
159
159
  from latticeai.tools.knowledge import * # noqa: E402,F401,F403
160
+ from latticeai.tools.local_files import * # noqa: E402,F401,F403
160
161
  from latticeai.tools.network import * # noqa: E402,F401,F403
161
- from latticeai.tools.commands import * # noqa: E402,F401,F403
162
162
 
163
163
 
164
164
  # ── tool registry: the single name → invocation source of truth ───────────────
@@ -11,19 +11,19 @@ from typing import Any, Dict, List, Optional
11
11
 
12
12
  import latticeai.tools as tools
13
13
  from latticeai.tools import (
14
- ToolError,
15
- ensure_agent_root,
16
- _resolve_path,
17
- _relative,
18
14
  ALLOWED_COMMANDS,
15
+ ALLOWED_GIT_SUBCOMMANDS,
19
16
  BLOCKED_COMMANDS,
20
17
  BUILD_SCRIPT_NAMES,
21
18
  DEPLOY_SCRIPT_NAMES,
22
- ALLOWED_GIT_SUBCOMMANDS,
23
- MAX_COMMAND_SECONDS,
24
19
  MAX_BUILD_SECONDS,
25
- MAX_DEPLOY_SECONDS,
26
20
  MAX_COMMAND_OUTPUT,
21
+ MAX_COMMAND_SECONDS,
22
+ MAX_DEPLOY_SECONDS,
23
+ ToolError,
24
+ _relative,
25
+ _resolve_path,
26
+ ensure_agent_root,
27
27
  )
28
28
 
29
29
  # find(1) flags that execute or delete; checked in run_command.
@@ -9,6 +9,7 @@ import subprocess
9
9
  import tempfile
10
10
  from typing import Any, Dict
11
11
 
12
+ from latticeai.core.quiet import quiet
12
13
  from latticeai.tools import ToolError
13
14
 
14
15
  _PLATFORM = platform.system()
@@ -27,7 +28,7 @@ def _init_computer_use():
27
28
  _pyautogui = _pag
28
29
  _CU_AVAILABLE = True
29
30
  except Exception:
30
- pass
31
+ quiet()
31
32
 
32
33
  _init_computer_use()
33
34
 
@@ -66,7 +67,7 @@ def computer_screenshot() -> Dict[str, Any]:
66
67
  if os.path.exists(tmp):
67
68
  os.unlink(tmp)
68
69
  except OSError:
69
- pass
70
+ quiet()
70
71
 
71
72
 
72
73
  def computer_open_app(app: str = "Google Chrome") -> Dict[str, Any]:
@@ -5,17 +5,18 @@ from __future__ import annotations
5
5
  from pathlib import Path
6
6
  from typing import Any, Dict, List
7
7
 
8
+ from latticeai.core.quiet import quiet
8
9
  from latticeai.tools import (
9
- ToolError,
10
- _resolve_path,
11
- _relative,
10
+ _CJK_FONT_CANDIDATES,
11
+ _SUPPORTED_READ_EXTENSIONS,
12
+ DOCUMENT_MAX_READ_BYTES,
12
13
  DOCUMENT_OUTPUT_DIR,
14
+ PDF_OUTPUT_DIR,
13
15
  PRESENTATION_OUTPUT_DIR,
14
16
  SPREADSHEET_OUTPUT_DIR,
15
- PDF_OUTPUT_DIR,
16
- DOCUMENT_MAX_READ_BYTES,
17
- _CJK_FONT_CANDIDATES,
18
- _SUPPORTED_READ_EXTENSIONS,
17
+ ToolError,
18
+ _relative,
19
+ _resolve_path,
19
20
  )
20
21
 
21
22
 
@@ -117,9 +118,9 @@ def create_pdf(title: str, body, filename: str = "document.pdf") -> Dict[str, An
117
118
  from reportlab.lib.pagesizes import A4
118
119
  from reportlab.lib.styles import ParagraphStyle
119
120
  from reportlab.lib.units import mm
120
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
121
121
  from reportlab.pdfbase import pdfmetrics
122
122
  from reportlab.pdfbase.ttfonts import TTFont
123
+ from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer
123
124
  except Exception as exc:
124
125
  raise ToolError("reportlab is not installed. Run `pip install reportlab`.") from exc
125
126
 
@@ -135,7 +136,7 @@ def create_pdf(title: str, body, filename: str = "document.pdf") -> Dict[str, An
135
136
  pdfmetrics.registerFont(TTFont("KoreanFont", font_path))
136
137
  font_name = "KoreanFont"
137
138
  except Exception:
138
- pass
139
+ quiet()
139
140
  break
140
141
 
141
142
  title_style = ParagraphStyle("Title", fontName=font_name, fontSize=18, spaceAfter=8, leading=24)
@@ -15,13 +15,14 @@ from pathlib import Path
15
15
  from typing import Any, Dict, List, Optional, Tuple
16
16
 
17
17
  import latticeai.tools as tools
18
+ from latticeai.core.quiet import quiet
18
19
  from latticeai.tools import (
19
- ToolError,
20
- ensure_agent_root,
21
- _resolve_path,
22
- _relative,
23
20
  MAX_FILE_BYTES,
24
21
  TEXT_EXTENSIONS,
22
+ ToolError,
23
+ _relative,
24
+ _resolve_path,
25
+ ensure_agent_root,
25
26
  )
26
27
 
27
28
 
@@ -219,6 +220,7 @@ def grep(
219
220
  try:
220
221
  lines = file_path.read_text(encoding="utf-8").splitlines()
221
222
  except (UnicodeDecodeError, OSError):
223
+ quiet()
222
224
  continue
223
225
 
224
226
  files_scanned += 1
@@ -340,6 +342,7 @@ def search_files(query: str, path: str = ".", max_results: int = 20) -> Dict[str
340
342
  try:
341
343
  lines = file_path.read_text(encoding="utf-8").splitlines()
342
344
  except UnicodeDecodeError:
345
+ quiet()
343
346
  continue
344
347
  for index, line in enumerate(lines, start=1):
345
348
  if query_lower in line.lower():
@@ -6,6 +6,7 @@ import hashlib
6
6
  from pathlib import Path
7
7
  from typing import Any, Dict, List, Optional
8
8
 
9
+ from latticeai.core.quiet import quiet
9
10
  from latticeai.services.p_reinforce import BRAIN_DIR, STRUCTURE
10
11
  from latticeai.tools import MAX_FILE_BYTES, ToolError
11
12
 
@@ -97,6 +98,7 @@ def knowledge_search(
97
98
  try:
98
99
  content = file_path.read_text(encoding="utf-8")
99
100
  except UnicodeDecodeError:
101
+ quiet()
100
102
  continue
101
103
  if query_lower in content.lower() or query_lower in file_path.name.lower():
102
104
  results.append(
@@ -6,7 +6,7 @@ from pathlib import Path
6
6
  from typing import Any, Dict
7
7
 
8
8
  from latticeai.core.tool_registry import LOCAL_WRITE_BLOCKED_PREFIXES
9
- from latticeai.tools import ToolError, LOCAL_MAX_FILE_BYTES
9
+ from latticeai.tools import LOCAL_MAX_FILE_BYTES, ToolError
10
10
 
11
11
 
12
12
  def local_list(path: str) -> Dict[str, Any]:
@@ -7,6 +7,7 @@ import socket
7
7
  import subprocess
8
8
  from typing import Any, Dict, List
9
9
 
10
+ from latticeai.core.quiet import quiet
10
11
 
11
12
 
12
13
  def _run_network_command(parts: List[str], timeout: int = 5) -> str:
@@ -44,7 +45,7 @@ def network_status() -> Dict[str, Any]:
44
45
  sock.connect(("8.8.8.8", 80))
45
46
  guessed_ip = sock.getsockname()[0]
46
47
  except Exception:
47
- pass
48
+ quiet()
48
49
  if guessed_ip and guessed_ip not in local_ips.values():
49
50
  local_ips["default_route"] = guessed_ip
50
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ltcai",
3
- "version": "10.0.0",
3
+ "version": "10.2.0",
4
4
  "description": "Lattice AI — local-first Digital Brain that keeps your knowledge durable across any AI model.",
5
5
  "homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  "check:python": "node scripts/run_python.mjs scripts/check_python.py",
27
27
  "lint": "npm run lint:python && node --check tests/visual/mock_server.cjs && node --check tests/visual/v3.spec.js && npm run lint:frontend && npm run frontend:openapi:check && node scripts/check_i18n_literals.mjs && npm run check:i18n-namespaces && npm run check:bundle && npm run check:legacy-debt && npm run test:browser-extension && npm run test:vscode-extension",
28
28
  "check:legacy-debt": "node scripts/check_legacy_debt.mjs",
29
- "lint:python": "node scripts/run_python.mjs -m ruff check .",
29
+ "lint:python": "node scripts/run_python.mjs -m ruff check . && npm run typecheck:python",
30
30
  "lint:frontend": "node scripts/lint_frontend.mjs",
31
31
  "check:bundle": "node scripts/check_bundle_budget.mjs",
32
32
  "docs:check-links": "node scripts/check_markdown_links.mjs && node scripts/check_doc_status.mjs",
@@ -59,7 +59,9 @@
59
59
  "publish:openvsx": "cd vscode-extension && npm run package:vsix && npm run publish:openvsx",
60
60
  "publish:all": "npm run release:artifacts && npm run release:validate && npm publish ltcai-$npm_package_version.tgz --access public && node scripts/run_python.mjs -m twine upload --skip-existing dist/ltcai-$npm_package_version.tar.gz dist/ltcai-$npm_package_version-py3-none-any.whl && cd vscode-extension && npm run publish:vscode && npm run publish:openvsx",
61
61
  "test:vscode-extension": "cd vscode-extension && npm run build && cd .. && node --test tests/vscode-extension.test.cjs",
62
- "check:i18n-namespaces": "node scripts/check_i18n_namespace_coverage.mjs"
62
+ "check:i18n-namespaces": "node scripts/check_i18n_namespace_coverage.mjs",
63
+ "typecheck:python": "node scripts/run_python.mjs -m mypy",
64
+ "test:coverage": "node scripts/run_python.mjs -m pytest tests/ -q --cov --cov-report=term:skip-covered"
63
65
  },
64
66
  "keywords": [
65
67
  "ltcai",
@@ -73,7 +73,6 @@ from latticeai.core.agent_prompts import ( # noqa: E402
73
73
  )
74
74
  from latticeai.tools import ToolError # noqa: E402
75
75
 
76
-
77
76
  # ── canonical smoke tasks ────────────────────────────────────────────────
78
77
  # Small, file-flavored tasks users actually ask for. The tool port is canned,
79
78
  # so the measurement is "can this model steer the real loop to completion",
@@ -82,7 +82,6 @@ from latticeai.core.file_generation import ( # noqa: E402
82
82
  validate_file_content,
83
83
  )
84
84
 
85
-
86
85
  # ── Scripted corpora ─────────────────────────────────────────────────────
87
86
  # Each entry is one model output for a canonical agent turn. The tiers encode
88
87
  # how the SAME intent degrades as model quality drops. All "should_parse=True"
@@ -18,9 +18,14 @@ if str(REPO_ROOT) not in sys.path:
18
18
 
19
19
  from lattice_brain.graph.store import KnowledgeGraphStore # noqa: E402
20
20
  from lattice_brain.quality import RetrievalBenchmarkRunner # noqa: E402
21
- from latticeai.services.search_service import SearchService # noqa: E402
21
+ from lattice_brain.retrieval_benchmark_fixtures import ( # noqa: E402
22
+ DOCUMENTS,
23
+ FIXTURE_NAME,
24
+ QUERIES,
25
+ TOP_K,
26
+ )
22
27
  from latticeai.services.memory_service import MemoryService # noqa: E402
23
- from lattice_brain.retrieval_benchmark_fixtures import DOCUMENTS, FIXTURE_NAME, QUERIES, TOP_K # noqa: E402
28
+ from latticeai.services.search_service import SearchService # noqa: E402
24
29
 
25
30
 
26
31
  class _EvalStore:
@@ -24,7 +24,8 @@ REPO = Path(__file__).resolve().parents[1]
24
24
  TARGETS = [
25
25
  ("latticeai/__init__.py", "regex", r'(__version__ = ")([^"]+)(")'),
26
26
  ("lattice_brain/__init__.py", "regex", r'(__version__ = ")([^"]+)(")'),
27
- ("latticeai/core/workspace_os.py", "regex", r'(WORKSPACE_OS_VERSION = ")([^"]+)(")'),
27
+ # Moved out of workspace_os.py in 10.2.0 when the vocabulary was split off.
28
+ ("latticeai/core/workspace_os_constants.py", "regex", r'(WORKSPACE_OS_VERSION = ")([^"]+)(")'),
28
29
  ("latticeai/core/marketplace.py", "regex", r'(MARKETPLACE_VERSION = ")([^"]+)(")'),
29
30
  ("lattice_brain/runtime/multi_agent.py", "regex", r'(MULTI_AGENT_VERSION = ")([^"]+)(")'),
30
31
  ("latticeai/services/architecture_readiness.py", "regex", r'(ARCHITECTURE_VERSION_TARGET = ")([^"]+)(")'),