ltcai 3.6.0 → 4.0.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 (169) hide show
  1. package/README.md +11 -7
  2. package/docs/V4_BRAIN_ARCHITECTURE.md +322 -0
  3. package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +509 -0
  4. package/docs/V4_IMPLEMENTATION_PLAN.md +470 -0
  5. package/docs/kg-schema.md +47 -53
  6. package/kg_schema.py +93 -10
  7. package/knowledge_graph.py +362 -33
  8. package/knowledge_graph_api.py +11 -127
  9. package/latticeai/__init__.py +1 -1
  10. package/latticeai/api/admin.py +1 -1
  11. package/latticeai/api/agents.py +7 -1
  12. package/latticeai/api/auth.py +27 -4
  13. package/latticeai/api/chat.py +112 -76
  14. package/latticeai/api/health.py +1 -1
  15. package/latticeai/api/hooks.py +1 -1
  16. package/latticeai/api/knowledge_graph.py +146 -0
  17. package/latticeai/api/local_files.py +1 -1
  18. package/latticeai/api/mcp.py +23 -11
  19. package/latticeai/api/memory.py +1 -1
  20. package/latticeai/api/models.py +1 -1
  21. package/latticeai/api/network.py +81 -0
  22. package/latticeai/api/realtime.py +1 -1
  23. package/latticeai/api/search.py +26 -2
  24. package/latticeai/api/security_dashboard.py +2 -3
  25. package/latticeai/api/setup.py +2 -2
  26. package/latticeai/api/static_routes.py +2 -4
  27. package/latticeai/api/tools.py +3 -0
  28. package/latticeai/api/workflow_designer.py +46 -0
  29. package/latticeai/api/workspace.py +71 -49
  30. package/latticeai/app_factory.py +1710 -0
  31. package/latticeai/brain/__init__.py +18 -0
  32. package/latticeai/brain/context.py +213 -0
  33. package/latticeai/brain/conversations.py +236 -0
  34. package/latticeai/brain/identity.py +175 -0
  35. package/latticeai/brain/memory.py +102 -0
  36. package/latticeai/brain/network.py +205 -0
  37. package/latticeai/core/agent.py +31 -7
  38. package/latticeai/core/audit.py +0 -7
  39. package/latticeai/core/config.py +1 -1
  40. package/latticeai/core/context_builder.py +1 -2
  41. package/latticeai/core/enterprise.py +1 -1
  42. package/latticeai/core/graph_curator.py +2 -2
  43. package/latticeai/core/marketplace.py +1 -1
  44. package/latticeai/core/mcp_registry.py +791 -0
  45. package/latticeai/core/model_compat.py +1 -1
  46. package/latticeai/core/model_resolution.py +0 -1
  47. package/latticeai/core/multi_agent.py +238 -4
  48. package/latticeai/core/security.py +1 -1
  49. package/latticeai/core/sessions.py +37 -7
  50. package/latticeai/core/workflow_engine.py +114 -2
  51. package/latticeai/core/workspace_os.py +58 -10
  52. package/latticeai/models/__init__.py +7 -0
  53. package/latticeai/models/router.py +779 -0
  54. package/latticeai/server_app.py +29 -1536
  55. package/latticeai/services/agent_runtime.py +1 -0
  56. package/latticeai/services/app_context.py +75 -14
  57. package/latticeai/services/ingestion.py +47 -0
  58. package/latticeai/services/kg_portability.py +33 -3
  59. package/latticeai/services/memory_service.py +39 -11
  60. package/latticeai/services/model_runtime.py +2 -5
  61. package/latticeai/services/platform_runtime.py +100 -23
  62. package/latticeai/services/search_service.py +17 -8
  63. package/latticeai/services/tool_dispatch.py +12 -2
  64. package/latticeai/services/triggers.py +241 -0
  65. package/latticeai/services/upload_service.py +37 -12
  66. package/latticeai/services/workspace_service.py +31 -0
  67. package/llm_router.py +29 -772
  68. package/ltcai_cli.py +1 -2
  69. package/mcp_registry.py +25 -788
  70. package/p_reinforce.py +124 -14
  71. package/package.json +9 -7
  72. package/scripts/bump_version.py +99 -0
  73. package/scripts/generate_diagrams.py +0 -1
  74. package/scripts/lint_v3.mjs +82 -18
  75. package/scripts/validate_release_artifacts.py +0 -1
  76. package/scripts/wheel_smoke.py +142 -0
  77. package/server.py +11 -7
  78. package/setup_wizard.py +1142 -0
  79. package/static/account.html +2 -4
  80. package/static/admin.html +3 -5
  81. package/static/chat.html +3 -6
  82. package/static/graph.html +2 -4
  83. package/static/sw.js +81 -52
  84. package/static/v3/asset-manifest.json +20 -19
  85. package/static/v3/css/{lattice.base.e4cdd05d.css → lattice.base.49deefb5.css} +1 -1
  86. package/static/v3/css/lattice.base.css +1 -1
  87. package/static/v3/css/{lattice.components.9b49d614.css → lattice.components.cde18231.css} +1 -1
  88. package/static/v3/css/lattice.components.css +1 -1
  89. package/static/v3/css/{lattice.shell.8fcc9d33.css → lattice.shell.29d36d85.css} +1 -1
  90. package/static/v3/css/lattice.shell.css +1 -1
  91. package/static/v3/css/{lattice.tokens.e7018963.css → lattice.tokens.304cbc40.css} +3 -0
  92. package/static/v3/css/lattice.tokens.css +3 -0
  93. package/static/v3/css/{lattice.views.22f69117.css → lattice.views.0a18b6c5.css} +2 -2
  94. package/static/v3/css/lattice.views.css +2 -2
  95. package/static/v3/index.html +3 -4
  96. package/static/v3/js/{app.c541f955.js → app.356e6452.js} +1 -1
  97. package/static/v3/js/core/{api.33d6320e.js → api.7a308b89.js} +1 -1
  98. package/static/v3/js/core/{routes.2ce3815a.js → routes.7222343d.js} +22 -22
  99. package/static/v3/js/core/routes.js +22 -22
  100. package/static/v3/js/core/{shell.8c163e0e.js → shell.a1657f20.js} +4 -4
  101. package/static/v3/js/core/shell.js +1 -1
  102. package/static/v3/js/core/{store.34ebd5e6.js → store.204a08b2.js} +1 -1
  103. package/static/v3/js/core/store.js +1 -1
  104. package/static/v3/js/views/graph-canvas.17c15d65.js +509 -0
  105. package/static/v3/js/views/graph-canvas.js +509 -0
  106. package/static/v3/js/views/{hybrid-search.b22b97e0.js → hybrid-search.2fb63ed9.js} +1 -2
  107. package/static/v3/js/views/hybrid-search.js +1 -2
  108. package/static/v3/js/views/{knowledge-graph.a96040a5.js → knowledge-graph.5e40cbeb.js} +33 -37
  109. package/static/v3/js/views/knowledge-graph.js +33 -37
  110. package/static/vendor/chart.umd.min.js +20 -0
  111. package/static/vendor/fonts/inter-latin-300-normal.woff2 +0 -0
  112. package/static/vendor/fonts/inter-latin-400-normal.woff2 +0 -0
  113. package/static/vendor/fonts/inter-latin-500-normal.woff2 +0 -0
  114. package/static/vendor/fonts/inter-latin-600-normal.woff2 +0 -0
  115. package/static/vendor/fonts/inter-latin-700-normal.woff2 +0 -0
  116. package/static/vendor/fonts/inter-latin-800-normal.woff2 +0 -0
  117. package/static/vendor/fonts/inter.css +44 -0
  118. package/static/vendor/icons/tabler-icons.min.css +4 -0
  119. package/static/vendor/icons/tabler-icons.woff2 +0 -0
  120. package/static/vendor/marked.min.js +69 -0
  121. package/static/workspace.html +2 -2
  122. package/telegram_bot.py +1 -2
  123. package/tools/commands.py +4 -2
  124. package/tools/computer.py +1 -1
  125. package/tools/documents.py +1 -3
  126. package/tools/filesystem.py +0 -4
  127. package/tools/knowledge.py +1 -3
  128. package/tools/network.py +1 -3
  129. package/codex_telegram_bot.py +0 -195
  130. package/docs/assets/v3.4.0/agent-run.png +0 -0
  131. package/docs/assets/v3.4.0/agents.png +0 -0
  132. package/docs/assets/v3.4.0/before/chat-before.png +0 -0
  133. package/docs/assets/v3.4.0/before/files-before.png +0 -0
  134. package/docs/assets/v3.4.0/chat.png +0 -0
  135. package/docs/assets/v3.4.0/connect-folder.png +0 -0
  136. package/docs/assets/v3.4.0/files.png +0 -0
  137. package/docs/assets/v3.4.0/home.png +0 -0
  138. package/docs/assets/v3.4.0/hooks-dispatch.png +0 -0
  139. package/docs/assets/v3.4.0/knowledge-graph.png +0 -0
  140. package/docs/assets/v3.4.0/local-agent.png +0 -0
  141. package/docs/assets/v3.4.0/memory.png +0 -0
  142. package/docs/assets/v3.4.0/settings.png +0 -0
  143. package/docs/assets/v3.4.0/vision-input.png +0 -0
  144. package/docs/assets/v3.4.0/workflows.png +0 -0
  145. package/docs/assets/v3.4.1/e2e_runtime_log.txt +0 -42
  146. package/docs/assets/v3.4.1/hooks-dispatch.png +0 -0
  147. package/docs/assets/v3.4.1/local-agent.png +0 -0
  148. package/docs/images/admin-dashboard.png +0 -0
  149. package/docs/images/architecture.png +0 -0
  150. package/docs/images/enterprise.png +0 -0
  151. package/docs/images/graph.png +0 -0
  152. package/docs/images/hero.gif +0 -0
  153. package/docs/images/knowledge-graph.png +0 -0
  154. package/docs/images/lattice-ai-demo.gif +0 -0
  155. package/docs/images/lattice-ai-hero.png +0 -0
  156. package/docs/images/logo.svg +0 -33
  157. package/docs/images/mobile-responsive.png +0 -0
  158. package/docs/images/model-recommendation.png +0 -0
  159. package/docs/images/onboarding.png +0 -0
  160. package/docs/images/organization.png +0 -0
  161. package/docs/images/pipeline.png +0 -0
  162. package/docs/images/screenshot-admin.png +0 -0
  163. package/docs/images/screenshot-chat.png +0 -0
  164. package/docs/images/screenshot-graph.png +0 -0
  165. package/docs/images/skills.png +0 -0
  166. package/docs/images/workspace-dark.png +0 -0
  167. package/docs/images/workspace-light.png +0 -0
  168. package/docs/images/workspace.png +0 -0
  169. package/requirements.txt +0 -16
@@ -10,10 +10,8 @@
10
10
  <meta name="apple-mobile-web-app-capable" content="yes">
11
11
  <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
12
12
  <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png">
13
- <link rel="preconnect" href="https://fonts.googleapis.com">
14
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap">
16
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
13
+ <link rel="stylesheet" href="/static/vendor/fonts/inter.css">
14
+ <link rel="stylesheet" href="/static/vendor/icons/tabler-icons.min.css">
17
15
  <link rel="stylesheet" href="/static/css/tokens.css">
18
16
  <link rel="stylesheet" href="/static/css/reference/base.css">
19
17
  <link rel="stylesheet" href="/static/css/reference/account.css">
package/static/admin.html CHANGED
@@ -11,10 +11,8 @@
11
11
  <meta name="apple-mobile-web-app-capable" content="yes">
12
12
  <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
13
13
  <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png">
14
- <link rel="preconnect" href="https://fonts.googleapis.com">
15
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
16
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap">
17
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
14
+ <link rel="stylesheet" href="/static/vendor/fonts/inter.css">
15
+ <link rel="stylesheet" href="/static/vendor/icons/tabler-icons.min.css">
18
16
  <link rel="stylesheet" href="/static/css/tokens.css">
19
17
  <link rel="stylesheet" href="/static/css/reference/base.css">
20
18
  <link rel="stylesheet" href="/static/css/reference/account.css">
@@ -22,7 +20,7 @@
22
20
  <link rel="stylesheet" href="/static/css/reference/graph.css">
23
21
  <link rel="stylesheet" href="/static/css/reference/chat.css">
24
22
  <link rel="stylesheet" href="/static/css/responsive.css">
25
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
23
+ <script src="/static/vendor/chart.umd.min.js"></script>
26
24
  </head>
27
25
 
28
26
  <body class="lattice-ref-admin">
package/static/chat.html CHANGED
@@ -16,12 +16,9 @@
16
16
  <meta name="apple-mobile-web-app-title" content="LatticeAI">
17
17
  <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
18
18
  <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png">
19
-
20
- <link rel="preconnect" href="https://fonts.googleapis.com">
21
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
22
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap">
23
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
24
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
19
+ <link rel="stylesheet" href="/static/vendor/fonts/inter.css">
20
+ <link rel="stylesheet" href="/static/vendor/icons/tabler-icons.min.css">
21
+ <script src="/static/vendor/marked.min.js"></script>
25
22
 
26
23
  <!-- ── Setup Wizard Styles ──────────────────────────────────────────── -->
27
24
  <link rel="stylesheet" href="/static/css/tokens.css">
package/static/graph.html CHANGED
@@ -5,10 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content">
6
6
  <title>Lattice AI - 지식 그래프</title>
7
7
  <script src="/static/scripts/ux.js"></script>
8
- <link rel="preconnect" href="https://fonts.googleapis.com">
9
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap">
11
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
8
+ <link rel="stylesheet" href="/static/vendor/fonts/inter.css">
9
+ <link rel="stylesheet" href="/static/vendor/icons/tabler-icons.min.css">
12
10
  <link rel="stylesheet" href="/static/css/tokens.css">
13
11
  <link rel="stylesheet" href="/static/css/reference/base.css">
14
12
  <link rel="stylesheet" href="/static/css/reference/account.css">
package/static/sw.js CHANGED
@@ -1,71 +1,100 @@
1
- // Lattice AI Service Worker — enables PWA install on Android/iOS
2
- // Strategy: network-first for API, cache-first for static assets.
3
- const CACHE = "ltcai-v310";
4
- const STATIC = [
5
- "/",
1
+ // Lattice Service Worker — PWA install + offline shell for the /app SPA.
2
+ // Strategy: precache the v3 bundle from its asset manifest (hashed files),
3
+ // cache-first for static assets, network-only for everything dynamic.
4
+ const CACHE = "lattice-v4";
5
+ const MANIFEST_URL = "/static/v3/asset-manifest.json";
6
+
7
+ // Non-manifest assets the shell needs offline.
8
+ const SHELL = [
6
9
  "/app",
7
- "/workspace",
8
- "/static/v3/asset-manifest.json",
9
- "/static/css/tokens.css",
10
- "/static/css/reference/base.css",
11
- "/static/css/reference/chat.css",
12
- "/static/css/responsive.css",
13
- "/static/workspace.css",
14
- "/static/scripts/chat.js",
15
- "/static/scripts/admin.js",
16
- "/static/scripts/graph.js",
17
- "/static/scripts/workspace.js",
18
- "/static/scripts/account.js",
10
+ MANIFEST_URL,
19
11
  "/manifest.json",
20
12
  "/icons/icon-192.png",
21
13
  "/icons/icon-512.png",
22
14
  "/icons/apple-touch-icon.png",
15
+ "/static/vendor/fonts/inter.css",
16
+ "/static/vendor/fonts/inter-latin-400-normal.woff2",
17
+ "/static/vendor/fonts/inter-latin-500-normal.woff2",
18
+ "/static/vendor/fonts/inter-latin-600-normal.woff2",
19
+ "/static/vendor/fonts/inter-latin-700-normal.woff2",
20
+ "/static/vendor/fonts/inter-latin-800-normal.woff2",
21
+ "/static/vendor/icons/tabler-icons.min.css",
22
+ "/static/vendor/icons/tabler-icons.woff2",
23
23
  ];
24
24
 
25
- self.addEventListener("install", e => {
26
- e.waitUntil(
27
- caches.open(CACHE).then(c => c.addAll(STATIC)).then(() => self.skipWaiting())
28
- );
25
+ async function precache() {
26
+ const cache = await caches.open(CACHE);
27
+ let manifestPaths = [];
28
+ try {
29
+ const res = await fetch(MANIFEST_URL, { cache: "no-cache" });
30
+ const manifest = await res.json();
31
+ const entry = manifest.entrypoints || {};
32
+ manifestPaths = [entry.app, ...(entry.styles || []), ...Object.values(manifest.assets || {})]
33
+ .filter(Boolean);
34
+ } catch (err) {
35
+ // Offline install: shell precache below still applies.
36
+ }
37
+ const unique = [...new Set([...SHELL, ...manifestPaths])];
38
+ await Promise.all(unique.map(async (path) => {
39
+ try {
40
+ const res = await fetch(path, { cache: "no-cache" });
41
+ if (res.ok) await cache.put(path, res);
42
+ } catch (err) {
43
+ // Missing one asset must not abort install; it just isn't offline-ready.
44
+ }
45
+ }));
46
+ }
47
+
48
+ self.addEventListener("install", (e) => {
49
+ e.waitUntil(precache().then(() => self.skipWaiting()));
29
50
  });
30
51
 
31
- self.addEventListener("activate", e => {
52
+ self.addEventListener("activate", (e) => {
32
53
  e.waitUntil(
33
- caches.keys().then(keys =>
34
- Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k)))
35
- ).then(() => clients.claim())
54
+ caches.keys()
55
+ .then((keys) => Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))))
56
+ .then(() => clients.claim())
36
57
  );
37
58
  });
38
59
 
39
- self.addEventListener("fetch", e => {
60
+ self.addEventListener("fetch", (e) => {
40
61
  const url = new URL(e.request.url);
62
+ if (e.request.method !== "GET" || url.origin !== self.location.origin) return;
41
63
 
42
- // API calls → always network (never cache)
43
- if (url.pathname.startsWith("/chat") ||
44
- url.pathname.startsWith("/agent") ||
45
- url.pathname.startsWith("/models") ||
46
- url.pathname.startsWith("/admin/") ||
47
- url.pathname.startsWith("/auth/") ||
48
- url.pathname.startsWith("/account/") ||
49
- url.pathname.startsWith("/vpc/") ||
50
- url.pathname.startsWith("/health") ||
51
- url.pathname.startsWith("/runtime_features") ||
52
- url.pathname.startsWith("/local") ||
53
- url.pathname.startsWith("/tools") ||
54
- url.pathname.startsWith("/knowledge") ||
55
- url.pathname.startsWith("/workspace/") ||
56
- url.pathname.startsWith("/history")) {
57
- e.respondWith(fetch(e.request));
64
+ const isStatic =
65
+ url.pathname.startsWith("/static/") ||
66
+ url.pathname.startsWith("/icons/") ||
67
+ url.pathname === "/manifest.json";
68
+
69
+ if (isStatic) {
70
+ // Hashed filenames make cache-first safe; unhashed files revalidate.
71
+ e.respondWith(
72
+ caches.match(e.request).then((hit) =>
73
+ hit ||
74
+ fetch(e.request).then((res) => {
75
+ const clone = res.clone();
76
+ if (res.ok) caches.open(CACHE).then((c) => c.put(e.request, clone));
77
+ return res;
78
+ })
79
+ )
80
+ );
58
81
  return;
59
82
  }
60
83
 
61
- // Static HTML network-first, fall back to cache
62
- e.respondWith(
63
- fetch(e.request)
64
- .then(res => {
65
- const clone = res.clone();
66
- caches.open(CACHE).then(c => c.put(e.request, clone));
67
- return res;
68
- })
69
- .catch(() => caches.match(e.request))
70
- );
84
+ if (url.pathname === "/app" || url.pathname.startsWith("/app/")) {
85
+ // SPA shell: network-first so updates land, cache fallback for offline.
86
+ e.respondWith(
87
+ fetch(e.request)
88
+ .then((res) => {
89
+ const clone = res.clone();
90
+ if (res.ok) caches.open(CACHE).then((c) => c.put("/app", clone));
91
+ return res;
92
+ })
93
+ .catch(() => caches.match("/app"))
94
+ );
95
+ return;
96
+ }
97
+
98
+ // Everything else (APIs, auth, realtime) is dynamic: network only —
99
+ // serving stale API responses would fabricate state.
71
100
  });
@@ -1,32 +1,32 @@
1
1
  {
2
- "version": "3.6.0",
2
+ "version": "4.0.0",
3
3
  "generated_at": "deterministic",
4
4
  "entrypoints": {
5
- "app": "/static/v3/js/app.c541f955.js",
5
+ "app": "/static/v3/js/app.356e6452.js",
6
6
  "styles": [
7
7
  "/static/css/tokens.3ba22e37.css",
8
- "/static/v3/css/lattice.tokens.e7018963.css",
9
- "/static/v3/css/lattice.base.e4cdd05d.css",
10
- "/static/v3/css/lattice.components.9b49d614.css",
11
- "/static/v3/css/lattice.shell.8fcc9d33.css",
12
- "/static/v3/css/lattice.views.22f69117.css"
8
+ "/static/v3/css/lattice.tokens.304cbc40.css",
9
+ "/static/v3/css/lattice.base.49deefb5.css",
10
+ "/static/v3/css/lattice.components.cde18231.css",
11
+ "/static/v3/css/lattice.shell.29d36d85.css",
12
+ "/static/v3/css/lattice.views.0a18b6c5.css"
13
13
  ]
14
14
  },
15
15
  "assets": {
16
16
  "static/css/tokens.css": "/static/css/tokens.3ba22e37.css",
17
- "static/v3/css/lattice.tokens.css": "/static/v3/css/lattice.tokens.e7018963.css",
18
- "static/v3/css/lattice.base.css": "/static/v3/css/lattice.base.e4cdd05d.css",
19
- "static/v3/css/lattice.components.css": "/static/v3/css/lattice.components.9b49d614.css",
20
- "static/v3/css/lattice.shell.css": "/static/v3/css/lattice.shell.8fcc9d33.css",
21
- "static/v3/css/lattice.views.css": "/static/v3/css/lattice.views.22f69117.css",
22
- "static/v3/js/app.js": "/static/v3/js/app.c541f955.js",
23
- "static/v3/js/core/api.js": "/static/v3/js/core/api.33d6320e.js",
17
+ "static/v3/css/lattice.tokens.css": "/static/v3/css/lattice.tokens.304cbc40.css",
18
+ "static/v3/css/lattice.base.css": "/static/v3/css/lattice.base.49deefb5.css",
19
+ "static/v3/css/lattice.components.css": "/static/v3/css/lattice.components.cde18231.css",
20
+ "static/v3/css/lattice.shell.css": "/static/v3/css/lattice.shell.29d36d85.css",
21
+ "static/v3/css/lattice.views.css": "/static/v3/css/lattice.views.0a18b6c5.css",
22
+ "static/v3/js/app.js": "/static/v3/js/app.356e6452.js",
23
+ "static/v3/js/core/api.js": "/static/v3/js/core/api.7a308b89.js",
24
24
  "static/v3/js/core/components.js": "/static/v3/js/core/components.f25b3b93.js",
25
25
  "static/v3/js/core/dom.js": "/static/v3/js/core/dom.a2773eb0.js",
26
26
  "static/v3/js/core/router.js": "/static/v3/js/core/router.584570f2.js",
27
- "static/v3/js/core/routes.js": "/static/v3/js/core/routes.2ce3815a.js",
28
- "static/v3/js/core/shell.js": "/static/v3/js/core/shell.8c163e0e.js",
29
- "static/v3/js/core/store.js": "/static/v3/js/core/store.34ebd5e6.js",
27
+ "static/v3/js/core/routes.js": "/static/v3/js/core/routes.7222343d.js",
28
+ "static/v3/js/core/shell.js": "/static/v3/js/core/shell.a1657f20.js",
29
+ "static/v3/js/core/store.js": "/static/v3/js/core/store.204a08b2.js",
30
30
  "static/v3/js/views/admin-audit.js": "/static/v3/js/views/admin-audit.660a1fb1.js",
31
31
  "static/v3/js/views/admin-permissions.js": "/static/v3/js/views/admin-permissions.a7ae5f09.js",
32
32
  "static/v3/js/views/admin-policies.js": "/static/v3/js/views/admin-policies.3658fd86.js",
@@ -36,10 +36,11 @@
36
36
  "static/v3/js/views/agents.js": "/static/v3/js/views/agents.014d0b74.js",
37
37
  "static/v3/js/views/chat.js": "/static/v3/js/views/chat.e6dd7dd0.js",
38
38
  "static/v3/js/views/files.js": "/static/v3/js/views/files.adad14c1.js",
39
+ "static/v3/js/views/graph-canvas.js": "/static/v3/js/views/graph-canvas.17c15d65.js",
39
40
  "static/v3/js/views/home.js": "/static/v3/js/views/home.24f8b8ae.js",
40
41
  "static/v3/js/views/hooks.js": "/static/v3/js/views/hooks.37895880.js",
41
- "static/v3/js/views/hybrid-search.js": "/static/v3/js/views/hybrid-search.b22b97e0.js",
42
- "static/v3/js/views/knowledge-graph.js": "/static/v3/js/views/knowledge-graph.a96040a5.js",
42
+ "static/v3/js/views/hybrid-search.js": "/static/v3/js/views/hybrid-search.2fb63ed9.js",
43
+ "static/v3/js/views/knowledge-graph.js": "/static/v3/js/views/knowledge-graph.5e40cbeb.js",
43
44
  "static/v3/js/views/marketplace.js": "/static/v3/js/views/marketplace.ab0583d4.js",
44
45
  "static/v3/js/views/mcp.js": "/static/v3/js/views/mcp.99b5c6a7.js",
45
46
  "static/v3/js/views/memory.js": "/static/v3/js/views/memory.4ebdf474.js",
@@ -111,7 +111,7 @@ code, pre, kbd, samp { font-family: var(--lt3-font-mono); }
111
111
  z-index: var(--lt3-z-toast);
112
112
  padding: var(--lt3-space-2) var(--lt3-space-4);
113
113
  background: var(--accent);
114
- color: #fff;
114
+ color: var(--lt3-on-accent);
115
115
  border-radius: var(--lt3-radius-sm);
116
116
  transform: translateY(-200%);
117
117
  transition: transform var(--lt3-dur-2) var(--lt3-ease);
@@ -111,7 +111,7 @@ code, pre, kbd, samp { font-family: var(--lt3-font-mono); }
111
111
  z-index: var(--lt3-z-toast);
112
112
  padding: var(--lt3-space-2) var(--lt3-space-4);
113
113
  background: var(--accent);
114
- color: #fff;
114
+ color: var(--lt3-on-accent);
115
115
  border-radius: var(--lt3-radius-sm);
116
116
  transform: translateY(-200%);
117
117
  transition: transform var(--lt3-dur-2) var(--lt3-ease);
@@ -87,7 +87,7 @@
87
87
  .lt3-btn[disabled] { opacity: 0.5; pointer-events: none; }
88
88
  .lt3-btn .ti { font-size: 1.05rem; }
89
89
 
90
- .lt3-btn--primary { background: var(--accent); color: #fff; box-shadow: var(--lt3-elev-1); }
90
+ .lt3-btn--primary { background: var(--accent); color: var(--lt3-on-accent); box-shadow: var(--lt3-elev-1); }
91
91
  .lt3-btn--primary:hover { background: var(--accent-deep); }
92
92
  .lt3-btn--ghost { background: var(--surface-2); border-color: var(--border); color: var(--text); }
93
93
  .lt3-btn--ghost:hover { border-color: var(--border-strong); background: var(--surface-3); }
@@ -87,7 +87,7 @@
87
87
  .lt3-btn[disabled] { opacity: 0.5; pointer-events: none; }
88
88
  .lt3-btn .ti { font-size: 1.05rem; }
89
89
 
90
- .lt3-btn--primary { background: var(--accent); color: #fff; box-shadow: var(--lt3-elev-1); }
90
+ .lt3-btn--primary { background: var(--accent); color: var(--lt3-on-accent); box-shadow: var(--lt3-elev-1); }
91
91
  .lt3-btn--primary:hover { background: var(--accent-deep); }
92
92
  .lt3-btn--ghost { background: var(--surface-2); border-color: var(--border); color: var(--text); }
93
93
  .lt3-btn--ghost:hover { border-color: var(--border-strong); background: var(--surface-3); }
@@ -36,7 +36,7 @@
36
36
  width: 34px; height: 34px; flex: none;
37
37
  border-radius: var(--lt3-radius-md);
38
38
  background: var(--text);
39
- color: #fff;
39
+ color: var(--lt3-on-accent);
40
40
  box-shadow: var(--lt3-elev-1);
41
41
  }
42
42
  .lt3-rail__logo svg { width: 22px; height: 22px; }
@@ -36,7 +36,7 @@
36
36
  width: 34px; height: 34px; flex: none;
37
37
  border-radius: var(--lt3-radius-md);
38
38
  background: var(--text);
39
- color: #fff;
39
+ color: var(--lt3-on-accent);
40
40
  box-shadow: var(--lt3-elev-1);
41
41
  }
42
42
  .lt3-rail__logo svg { width: 22px; height: 22px; }
@@ -98,6 +98,9 @@
98
98
  --lt3-pillar-graph: var(--accent); /* blue — relational structure */
99
99
  --lt3-pillar-vector: var(--accent-2); /* teal — embeddings field */
100
100
  --lt3-pillar-hybrid: var(--accent-pink); /* magenta — fusion of both */
101
+
102
+ /* Text rendered on saturated accent fills (both themes keep accents dark-safe). */
103
+ --lt3-on-accent: #ffffff;
101
104
  --lt3-pillar-graph-soft: color-mix(in srgb, var(--lt3-pillar-graph) 14%, transparent);
102
105
  --lt3-pillar-vector-soft: color-mix(in srgb, var(--lt3-pillar-vector) 16%, transparent);
103
106
  --lt3-pillar-hybrid-soft: color-mix(in srgb, var(--lt3-pillar-hybrid) 16%, transparent);
@@ -98,6 +98,9 @@
98
98
  --lt3-pillar-graph: var(--accent); /* blue — relational structure */
99
99
  --lt3-pillar-vector: var(--accent-2); /* teal — embeddings field */
100
100
  --lt3-pillar-hybrid: var(--accent-pink); /* magenta — fusion of both */
101
+
102
+ /* Text rendered on saturated accent fills (both themes keep accents dark-safe). */
103
+ --lt3-on-accent: #ffffff;
101
104
  --lt3-pillar-graph-soft: color-mix(in srgb, var(--lt3-pillar-graph) 14%, transparent);
102
105
  --lt3-pillar-vector-soft: color-mix(in srgb, var(--lt3-pillar-vector) 16%, transparent);
103
106
  --lt3-pillar-hybrid-soft: color-mix(in srgb, var(--lt3-pillar-hybrid) 16%, transparent);
@@ -222,12 +222,12 @@
222
222
  .lt3-msg--user { align-self: flex-end; flex-direction: row-reverse; max-width: 90%; }
223
223
  .lt3-msg--ai { align-self: flex-start; max-width: 100%; }
224
224
  .lt3-msg__avatar { width: 32px; height: 32px; flex: none; border-radius: var(--lt3-radius-sm); display: grid; place-items: center; }
225
- .lt3-msg--ai .lt3-msg__avatar { background: linear-gradient(135deg, var(--lt3-pillar-graph), var(--lt3-pillar-vector)); color: #fff; }
225
+ .lt3-msg--ai .lt3-msg__avatar { background: linear-gradient(135deg, var(--lt3-pillar-graph), var(--lt3-pillar-vector)); color: var(--lt3-on-accent); }
226
226
  .lt3-msg--user .lt3-msg__avatar { background: var(--surface-3); color: var(--muted); }
227
227
  .lt3-msg__body { min-width: 0; display: flex; flex-direction: column; gap: var(--lt3-space-2); }
228
228
  .lt3-msg__bubble { padding: var(--lt3-space-3) var(--lt3-space-4); border-radius: var(--lt3-radius-md); font-size: var(--lt3-text-md); line-height: var(--lt3-leading-normal); white-space: pre-wrap; overflow-wrap: anywhere; }
229
229
  .lt3-msg--ai .lt3-msg__bubble { background: var(--surface); border: 1px solid var(--border); }
230
- .lt3-msg--user .lt3-msg__bubble { background: var(--accent); color: #fff; }
230
+ .lt3-msg--user .lt3-msg__bubble { background: var(--accent); color: var(--lt3-on-accent); }
231
231
  .lt3-msg__cites { display: flex; flex-wrap: wrap; gap: var(--lt3-space-2); }
232
232
  .lt3-typing { display: inline-flex; gap: 4px; align-items: center; padding: var(--lt3-space-1) 0; }
233
233
  .lt3-typing i { width: 6px; height: 6px; border-radius: 99px; background: var(--faint); animation: lt3-bounce 1s var(--lt3-ease) infinite; }
@@ -222,12 +222,12 @@
222
222
  .lt3-msg--user { align-self: flex-end; flex-direction: row-reverse; max-width: 90%; }
223
223
  .lt3-msg--ai { align-self: flex-start; max-width: 100%; }
224
224
  .lt3-msg__avatar { width: 32px; height: 32px; flex: none; border-radius: var(--lt3-radius-sm); display: grid; place-items: center; }
225
- .lt3-msg--ai .lt3-msg__avatar { background: linear-gradient(135deg, var(--lt3-pillar-graph), var(--lt3-pillar-vector)); color: #fff; }
225
+ .lt3-msg--ai .lt3-msg__avatar { background: linear-gradient(135deg, var(--lt3-pillar-graph), var(--lt3-pillar-vector)); color: var(--lt3-on-accent); }
226
226
  .lt3-msg--user .lt3-msg__avatar { background: var(--surface-3); color: var(--muted); }
227
227
  .lt3-msg__body { min-width: 0; display: flex; flex-direction: column; gap: var(--lt3-space-2); }
228
228
  .lt3-msg__bubble { padding: var(--lt3-space-3) var(--lt3-space-4); border-radius: var(--lt3-radius-md); font-size: var(--lt3-text-md); line-height: var(--lt3-leading-normal); white-space: pre-wrap; overflow-wrap: anywhere; }
229
229
  .lt3-msg--ai .lt3-msg__bubble { background: var(--surface); border: 1px solid var(--border); }
230
- .lt3-msg--user .lt3-msg__bubble { background: var(--accent); color: #fff; }
230
+ .lt3-msg--user .lt3-msg__bubble { background: var(--accent); color: var(--lt3-on-accent); }
231
231
  .lt3-msg__cites { display: flex; flex-wrap: wrap; gap: var(--lt3-space-2); }
232
232
  .lt3-typing { display: inline-flex; gap: 4px; align-items: center; padding: var(--lt3-space-1) 0; }
233
233
  .lt3-typing i { width: 6px; height: 6px; border-radius: 99px; background: var(--faint); animation: lt3-bounce 1s var(--lt3-ease) infinite; }
@@ -18,10 +18,9 @@
18
18
 
19
19
  <link rel="manifest" href="/manifest.json">
20
20
  <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png">
21
- <link rel="preconnect" href="https://fonts.googleapis.com">
22
- <link rel="preconnect" href="https://cdn.jsdelivr.net">
23
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap">
24
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
21
+ <!-- Fonts and icons are vendored locally: no CDN calls from shipped pages. -->
22
+ <link rel="stylesheet" href="/static/vendor/fonts/inter.css">
23
+ <link rel="stylesheet" href="/static/vendor/icons/tabler-icons.min.css">
25
24
 
26
25
  <script>
27
26
  window.__LT_ASSET_SOURCES__ = {
@@ -3,7 +3,7 @@
3
3
  * Boots the shell. Views are lazy-loaded by the router (see core/routes.js).
4
4
  * ========================================================================== */
5
5
 
6
- import { boot } from "./core/shell.8c163e0e.js";
6
+ import { boot } from "./core/shell.a1657f20.js";
7
7
 
8
8
  const root = document.getElementById("app");
9
9
  if (root) boot(root);
@@ -11,7 +11,7 @@
11
11
  * "unavailable" → endpoint missing/down; no fake payload
12
12
  * ========================================================================== */
13
13
 
14
- import { store } from "./store.34ebd5e6.js";
14
+ import { store } from "./store.204a08b2.js";
15
15
 
16
16
  const TIMEOUT_MS = 8000;
17
17
  const EMPTY_INDEX_STATUS = { generated_at: null, pipelines: {}, sources: [] };
@@ -10,11 +10,11 @@ export const MODE_RANK = { basic: 0, advanced: 1, admin: 2 };
10
10
 
11
11
  /** Nav groups in display order. */
12
12
  export const GROUPS = [
13
- { id: "workspace", label: "Workspace" },
14
- { id: "data", label: "Data" },
15
- { id: "retrieval", label: "Retrieval" },
16
- { id: "compute", label: "Compute" },
17
- { id: "platform", label: "Platform" },
13
+ { id: "brain", label: "Brain" },
14
+ { id: "ask", label: "Ask" },
15
+ { id: "capture", label: "Capture" },
16
+ { id: "act", label: "Act" },
17
+ { id: "library", label: "Library" },
18
18
  { id: "system", label: "System" },
19
19
  { id: "admin", label: "Administration", adminOnly: true },
20
20
  ];
@@ -25,37 +25,37 @@ export const GROUPS = [
25
25
  */
26
26
  export const ROUTES = [
27
27
  // Workspace
28
- { key: "home", label: "Home", icon: "layout-dashboard", group: "workspace", minMode: "basic", view: "home", title: "Home", desc: "Your local-first AI workspace at a glance." },
29
- { key: "chat", label: "Chat", icon: "message-2", group: "workspace", minMode: "basic", view: "chat", title: "Chat", desc: "Grounded conversation over your indexed workspace." },
28
+ { key: "home", label: "Overview", icon: "layout-dashboard", group: "system", minMode: "basic", view: "home", title: "Overview", desc: "Your digital brain at a glance." },
29
+ { key: "chat", label: "Chat", icon: "message-2", group: "ask", minMode: "basic", view: "chat", title: "Chat", desc: "Grounded conversation over your brain — memories, knowledge, and notes assembled with provenance." },
30
30
 
31
31
  // Data
32
- { key: "files", label: "Files", icon: "folders", group: "data", minMode: "basic", view: "files", title: "Files", desc: "Connected sources and indexed documents." },
32
+ { key: "files", label: "Files", icon: "folders", group: "capture", minMode: "basic", view: "files", title: "Files", desc: "Connected sources and indexed documents." },
33
33
 
34
34
  // Retrieval (the product identity)
35
- { key: "hybrid-search", label: "Search", icon: "arrows-join", group: "retrieval", minMode: "basic", view: "hybrid-search", title: "Hybrid Search", desc: "Graph structure fused with vector similarity." },
36
- { key: "knowledge-graph", label: "Knowledge", icon: "chart-dots-3", group: "retrieval", minMode: "basic", view: "knowledge-graph", title: "Knowledge Graph", desc: "Your digital brain — every source converges here. Explore, ingest, and export." },
37
- { key: "memory", label: "Memory", icon: "brain", group: "retrieval", minMode: "basic", view: "memory", title: "Memory", desc: "Long-term workspace, project, agent, and conversation memory." },
35
+ { key: "hybrid-search", label: "Search", icon: "arrows-join", group: "brain", minMode: "basic", view: "hybrid-search", title: "Hybrid Search", desc: "Graph structure fused with vector similarity." },
36
+ { key: "knowledge-graph", label: "Knowledge Graph", icon: "chart-dots-3", group: "brain", minMode: "basic", view: "knowledge-graph", title: "Knowledge Graph", desc: "Your digital brain — every source converges here. Explore, ingest, and export." },
37
+ { key: "memory", label: "Memory", icon: "brain", group: "brain", minMode: "basic", view: "memory", title: "Memory", desc: "Long-term workspace, project, agent, and conversation memory." },
38
38
 
39
39
  // Compute
40
- { key: "models", label: "Models", icon: "cpu", group: "compute", minMode: "basic", view: "models", title: "Models", desc: "Local MLX models and embeddings." },
41
- { key: "agents", label: "Agents", icon: "robot", group: "compute", minMode: "advanced", view: "agents", title: "Agents", desc: "Multi-agent roles, runs, and handoffs." },
42
- { key: "workflows", label: "Workflows", icon: "sitemap", group: "compute", minMode: "advanced", view: "workflows", title: "Workflow Agents", desc: "Trigger → agent chain → tools → memory → result." },
40
+ { key: "models", label: "Models", icon: "cpu", group: "library", minMode: "basic", view: "models", title: "Models", desc: "Local MLX models and embeddings." },
41
+ { key: "agents", label: "Agents", icon: "robot", group: "act", minMode: "advanced", view: "agents", title: "Agents", desc: "Multi-agent roles, runs, and handoffs." },
42
+ { key: "workflows", label: "Workflows", icon: "sitemap", group: "act", minMode: "advanced", view: "workflows", title: "Workflow Agents", desc: "Trigger → agent chain → tools → memory → result." },
43
43
 
44
44
  // Platform (the agent ecosystem)
45
- { key: "skills", label: "Skills", icon: "puzzle", group: "platform", minMode: "advanced", view: "skills", title: "Skills", desc: "Install, enable, and manage skills." },
46
- { key: "hooks", label: "Hooks", icon: "webhook", group: "platform", minMode: "advanced", view: "hooks", title: "Hooks", desc: "Lifecycle hooks across runs, tools, and workflows." },
47
- { key: "mcp", label: "MCP", icon: "plug-connected", group: "platform", minMode: "advanced", view: "mcp", title: "MCP Manager", desc: "Connected MCP servers, available tools, and health." },
45
+ { key: "skills", label: "Skills", icon: "puzzle", group: "library", minMode: "advanced", view: "skills", title: "Skills", desc: "Install, enable, and manage skills." },
46
+ { key: "hooks", label: "Hooks", icon: "webhook", group: "act", minMode: "advanced", view: "hooks", title: "Hooks", desc: "Lifecycle hooks across runs, tools, and workflows." },
47
+ { key: "mcp", label: "MCP", icon: "plug-connected", group: "library", minMode: "advanced", view: "mcp", title: "MCP Manager", desc: "Connected MCP servers, available tools, and health." },
48
48
 
49
49
  // System
50
50
  { key: "settings", label: "Settings", icon: "settings", group: "system", minMode: "basic", view: "settings", title: "Settings", desc: "Appearance, workspace, and integrations." },
51
51
 
52
52
  // Deep-linkable legacy/experimental surfaces. They remain renderable for
53
53
  // compatibility, but are not promoted in the production navigation.
54
- { key: "pipeline", label: "Pipeline", icon: "git-branch", group: "data", minMode: "advanced", view: "pipeline", title: "Pipeline", desc: "Ingest, embed, and graph-build flows.", hidden: true },
55
- { key: "planning", label: "Planning", icon: "target-arrow", group: "compute", minMode: "advanced", view: "planning", title: "Autonomous Planning", desc: "Goal → plan → execute → review → replan.", hidden: true },
56
- { key: "my-computer", label: "My Computer", icon: "device-desktop-analytics", group: "compute", minMode: "advanced", view: "my-computer", title: "My Computer", desc: "Local hardware, memory, and runtime.", hidden: true },
57
- { key: "marketplace", label: "Marketplace", icon: "building-store", group: "platform", minMode: "advanced", view: "marketplace", title: "Marketplace", desc: "Agent templates, agents, plugins, and skills.", hidden: true },
58
- { key: "tools", label: "Tools", icon: "tools", group: "platform", minMode: "advanced", view: "tools", title: "Tool Registry", desc: "Local, workspace, and MCP tools with governance.", hidden: true },
54
+ { key: "pipeline", label: "Pipeline", icon: "git-branch", group: "capture", minMode: "advanced", view: "pipeline", title: "Pipeline", desc: "Ingest, embed, and graph-build flows.", hidden: true },
55
+ { key: "planning", label: "Planning", icon: "target-arrow", group: "act", minMode: "advanced", view: "planning", title: "Autonomous Planning", desc: "Goal → plan → execute → review → replan.", hidden: true },
56
+ { key: "my-computer", label: "My Computer", icon: "device-desktop-analytics", group: "system", minMode: "advanced", view: "my-computer", title: "My Computer", desc: "Local hardware, memory, and runtime.", hidden: true },
57
+ { key: "marketplace", label: "Marketplace", icon: "building-store", group: "library", minMode: "advanced", view: "marketplace", title: "Marketplace", desc: "Agent templates, agents, plugins, and skills.", hidden: true },
58
+ { key: "tools", label: "Tools", icon: "tools", group: "act", minMode: "advanced", view: "tools", title: "Tool Registry", desc: "Local, workspace, and MCP tools with governance.", hidden: true },
59
59
 
60
60
  // Admin
61
61
  { key: "admin/users", label: "Users", icon: "users", group: "admin", minMode: "admin", view: "admin-users", title: "Users", desc: "Workspace members and access.", admin: true },