ltcai 4.6.1 → 4.7.2

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 (34) hide show
  1. package/README.md +74 -40
  2. package/docs/CHANGELOG.md +141 -0
  3. package/docs/PRODUCT_DIRECTION_REVIEW.md +88 -0
  4. package/docs/V4_7_0_ADMIN_SEPARATION_REPORT.md +42 -0
  5. package/docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md +49 -0
  6. package/docs/V4_7_2_INTUITIVE_BRAIN_UX_REPORT.md +62 -0
  7. package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +22 -19
  8. package/frontend/src/App.tsx +627 -8
  9. package/frontend/src/api/client.ts +11 -1
  10. package/frontend/src/components/ProductFlow.tsx +106 -51
  11. package/frontend/src/pages/System.tsx +1 -1
  12. package/frontend/src/styles.css +905 -81
  13. package/lattice_brain/__init__.py +1 -1
  14. package/lattice_brain/archive.py +86 -13
  15. package/lattice_brain/portability.py +82 -14
  16. package/lattice_brain/runtime/multi_agent.py +1 -1
  17. package/latticeai/__init__.py +1 -1
  18. package/latticeai/api/admin.py +141 -6
  19. package/latticeai/api/chat.py +35 -13
  20. package/latticeai/app_factory.py +8 -4
  21. package/latticeai/core/audit.py +3 -2
  22. package/latticeai/core/marketplace.py +1 -1
  23. package/latticeai/core/workspace_os.py +1 -1
  24. package/package.json +2 -1
  25. package/src-tauri/Cargo.lock +1 -1
  26. package/src-tauri/Cargo.toml +1 -1
  27. package/src-tauri/tauri.conf.json +1 -1
  28. package/static/app/asset-manifest.json +5 -5
  29. package/static/app/assets/index-DdAB4yfa.js +16 -0
  30. package/static/app/assets/index-DdAB4yfa.js.map +1 -0
  31. package/static/app/assets/{index-7U86v70r.css → index-KlQ04wVv.css} +1 -1
  32. package/static/app/index.html +2 -2
  33. package/static/app/assets/index-D1jAPQws.js +0 -16
  34. package/static/app/assets/index-D1jAPQws.js.map +0 -1
@@ -15,7 +15,7 @@ lazily via module ``__getattr__`` for backwards compatibility.
15
15
  from __future__ import annotations
16
16
 
17
17
  import threading
18
- from typing import TYPE_CHECKING, Any, Dict, Optional
18
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
19
19
 
20
20
  if TYPE_CHECKING: # imports for annotations only — keep module import light
21
21
  from fastapi import FastAPI
@@ -51,8 +51,6 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
51
51
  except Exception as e:
52
52
  print(f"⚠️ MLX Metal context unavailable: {e}")
53
53
  mx = None
54
- from typing import List
55
-
56
54
  import uvicorn
57
55
  from fastapi import FastAPI, HTTPException, Request
58
56
  from fastapi.middleware.cors import CORSMiddleware
@@ -704,6 +702,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
704
702
  user_nickname: Optional[str] = None,
705
703
  source: Optional[str] = None,
706
704
  conversation_id: Optional[str] = None,
705
+ workspace_id: Optional[str] = None,
707
706
  ):
708
707
  try:
709
708
  message = redact_secret_text(message)
@@ -718,6 +717,8 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
718
717
  item["source"] = source
719
718
  if conversation_id:
720
719
  item["conversation_id"] = conversation_id
720
+ if workspace_id:
721
+ item["workspace_id"] = workspace_id
721
722
  sensitive = classify_sensitive_message(item, -1)
722
723
  append_audit_event(
723
724
  "chat_message",
@@ -726,6 +727,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
726
727
  user_nickname=user_nickname,
727
728
  source=source,
728
729
  conversation_id=conversation_id,
730
+ workspace_id=workspace_id,
729
731
  content_preview=sensitive.get("preview"),
730
732
  content_chars=len(message or ""),
731
733
  sensitivity=sensitive.get("sensitivity"),
@@ -1036,7 +1038,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
1036
1038
  return _build_sensitivity_report(history)
1037
1039
 
1038
1040
  # ── Admin audit report — delegated to latticeai.core.audit ───────────────────
1039
- def build_admin_audit_report(users: Dict) -> Dict:
1041
+ def build_admin_audit_report(users: Dict, audit_events: Optional[List[Dict]] = None) -> Dict:
1040
1042
  graph_stats = None
1041
1043
  try:
1042
1044
  if ENABLE_GRAPH and KNOWLEDGE_GRAPH:
@@ -1047,6 +1049,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
1047
1049
  AUDIT_FILE, users,
1048
1050
  get_user_role=get_user_role,
1049
1051
  graph_stats=graph_stats,
1052
+ audit_events=audit_events,
1050
1053
  )
1051
1054
 
1052
1055
  router = LLMRouter()
@@ -1268,6 +1271,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
1268
1271
  require_admin=require_admin, require_user=require_user,
1269
1272
  load_users=load_users, save_users=save_users,
1270
1273
  get_user_role=get_user_role, get_history=get_history,
1274
+ get_audit_log=get_audit_log,
1271
1275
  public_user=public_user, load_vpc_config=load_vpc_config,
1272
1276
  save_vpc_config=save_vpc_config,
1273
1277
  build_admin_audit_report=build_admin_audit_report,
@@ -141,8 +141,9 @@ def build_admin_audit_report(
141
141
  *,
142
142
  get_user_role: Callable[[str, Optional[Dict]], str],
143
143
  graph_stats: Optional[Dict] = None,
144
+ audit_events: Optional[List[Dict]] = None,
144
145
  ) -> Dict:
145
- events = get_audit_log(audit_file)
146
+ events = audit_events if audit_events is not None else get_audit_log(audit_file)
146
147
 
147
148
  def _user_bucket(email: Optional[str], nickname: Optional[str] = None) -> Dict:
148
149
  user = users.get(email or "", {})
@@ -234,7 +235,7 @@ def build_admin_audit_report(
234
235
  def _public_audit_event(event: Dict) -> Dict:
235
236
  allowed = {
236
237
  "event_type", "timestamp", "role", "user_email", "user_nickname", "source",
237
- "conversation_id", "command", "scope", "target_email", "filename", "mime_type",
238
+ "conversation_id", "workspace_id", "command", "scope", "target_email", "filename", "mime_type",
238
239
  "ext", "bytes", "extracted_chars", "graph_node", "keep_last", "removed", "kept",
239
240
  "started_at", "sensitivity", "sensitive_labels", "content_preview", "content_chars",
240
241
  }
@@ -11,7 +11,7 @@ from copy import deepcopy
11
11
  from typing import Any, Dict, List, Optional
12
12
 
13
13
 
14
- MARKETPLACE_VERSION = "4.6.1"
14
+ MARKETPLACE_VERSION = "4.7.2"
15
15
  TEMPLATE_KINDS = ("plugin", "workflow", "agent")
16
16
 
17
17
 
@@ -19,7 +19,7 @@ from pathlib import Path
19
19
  from typing import Any, Callable, Dict, Iterable, List, Optional
20
20
 
21
21
 
22
- WORKSPACE_OS_VERSION = "4.6.1"
22
+ WORKSPACE_OS_VERSION = "4.7.2"
23
23
 
24
24
  # Workspace types separate single-user Personal workspaces from shared
25
25
  # Organization workspaces. Both keep the same local-first JSON store; the type
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ltcai",
3
- "version": "4.6.1",
3
+ "version": "4.7.2",
4
4
  "description": "Lattice AI — local-first Living Brain workspace (conversation, durable memory, hybrid search, agents, advanced graph exploration, portable encrypted brain archives)",
5
5
  "homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
6
6
  "repository": {
@@ -89,6 +89,7 @@
89
89
  "static/icons/",
90
90
  "plugins/",
91
91
  "scripts/",
92
+ "!scripts/launch-pts-grok.sh",
92
93
  "!docs/images/tmp_frames/",
93
94
  "!**/__pycache__/",
94
95
  "!**/*.pyc",
@@ -1654,7 +1654,7 @@ dependencies = [
1654
1654
 
1655
1655
  [[package]]
1656
1656
  name = "lattice-ai-desktop"
1657
- version = "4.6.1"
1657
+ version = "4.7.2"
1658
1658
  dependencies = [
1659
1659
  "plist",
1660
1660
  "serde",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "lattice-ai-desktop"
3
- version = "4.6.1"
3
+ version = "4.7.2"
4
4
  description = "Lattice AI Digital Brain desktop shell"
5
5
  authors = ["TaeSoo Park"]
6
6
  edition = "2021"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://schema.tauri.app/config/2",
3
3
  "productName": "Lattice AI",
4
- "version": "4.6.1",
4
+ "version": "4.7.2",
5
5
  "identifier": "ai.lattice.desktop",
6
6
  "build": {
7
7
  "beforeDevCommand": "npm run frontend:dev",
@@ -1,13 +1,13 @@
1
1
  {
2
- "version": "4.6.1",
2
+ "version": "4.7.2",
3
3
  "generated_at": "vite",
4
4
  "entrypoints": {
5
5
  "app": "/static/app/index.html"
6
6
  },
7
7
  "assets": {
8
8
  "../node_modules/@tauri-apps/api/core.js": "/static/app/assets/core-CwxXejkd.js",
9
- "index.html": "/static/app/assets/index-D1jAPQws.js",
10
- "assets/index-7U86v70r.css": "/static/app/assets/index-7U86v70r.css"
9
+ "index.html": "/static/app/assets/index-DdAB4yfa.js",
10
+ "assets/index-KlQ04wVv.css": "/static/app/assets/index-KlQ04wVv.css"
11
11
  },
12
12
  "vite": {
13
13
  "../node_modules/@tauri-apps/api/core.js": {
@@ -17,7 +17,7 @@
17
17
  "isDynamicEntry": true
18
18
  },
19
19
  "index.html": {
20
- "file": "assets/index-D1jAPQws.js",
20
+ "file": "assets/index-DdAB4yfa.js",
21
21
  "name": "index",
22
22
  "src": "index.html",
23
23
  "isEntry": true,
@@ -25,7 +25,7 @@
25
25
  "../node_modules/@tauri-apps/api/core.js"
26
26
  ],
27
27
  "css": [
28
- "assets/index-7U86v70r.css"
28
+ "assets/index-KlQ04wVv.css"
29
29
  ]
30
30
  }
31
31
  }