ltcai 4.3.0 → 4.3.1
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.
- package/README.md +19 -17
- package/bin/ltcai.js +6 -2
- package/docs/CHANGELOG.md +33 -3
- package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +16 -22
- package/frontend/openapi.json +11 -1
- package/frontend/src/App.tsx +15 -1
- package/frontend/src/api/client.ts +19 -1
- package/frontend/src/api/openapi.ts +10 -0
- package/frontend/src/pages/Act.tsx +63 -2
- package/frontend/src/pages/Library.tsx +9 -3
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/archive.py +3 -3
- package/lattice_brain/storage/sqlite.py +15 -2
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/agents.py +3 -1
- package/latticeai/api/models.py +66 -18
- package/latticeai/brain/projection.py +12 -2
- package/latticeai/brain/retrieval.py +10 -0
- package/latticeai/brain/store.py +6 -1
- package/latticeai/core/config.py +3 -1
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/multi_agent.py +1 -1
- package/latticeai/core/product_hardening.py +2 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/latticeai/services/agent_runtime.py +52 -12
- package/latticeai/services/model_runtime.py +83 -2
- package/ltcai_cli.py +14 -3
- package/package.json +3 -2
- package/requirements.txt +17 -0
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/main.rs +257 -25
- package/src-tauri/tauri.conf.json +20 -1
- package/static/app/asset-manifest.json +3 -3
- package/static/app/assets/{index-RiJTJliG.js → index-BhPuj8rT.js} +45 -45
- package/static/app/assets/index-BhPuj8rT.js.map +1 -0
- package/static/app/index.html +1 -1
- package/static/app/assets/index-RiJTJliG.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ltcai",
|
|
3
|
-
"version": "4.3.
|
|
4
|
-
"description": "Lattice AI — local-first Digital Brain Platform (knowledge graph, durable memory, hybrid search, agents,
|
|
3
|
+
"version": "4.3.1",
|
|
4
|
+
"description": "Lattice AI — local-first Digital Brain Platform (knowledge graph, durable memory, hybrid search, agents, portable encrypted brain archives)",
|
|
5
5
|
"homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"files": [
|
|
69
69
|
"bin/ltcai.js",
|
|
70
70
|
"LICENSE",
|
|
71
|
+
"requirements.txt",
|
|
71
72
|
"ltcai_cli.py",
|
|
72
73
|
"auto_setup.py",
|
|
73
74
|
"server.py",
|
package/requirements.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
fastapi>=0.110,<1
|
|
2
|
+
uvicorn>=0.29,<1
|
|
3
|
+
pydantic>=2.7,<3
|
|
4
|
+
httpx>=0.27,<1
|
|
5
|
+
pillow>=10,<13
|
|
6
|
+
openai>=1.30,<3
|
|
7
|
+
python-docx>=1.1,<2
|
|
8
|
+
openpyxl>=3.1,<4
|
|
9
|
+
python-pptx>=0.6.23,<2
|
|
10
|
+
python-multipart>=0.0.9,<0.1
|
|
11
|
+
keyring>=24,<26
|
|
12
|
+
authlib>=1.3,<2
|
|
13
|
+
cryptography>=42,<49
|
|
14
|
+
pdfplumber>=0.11,<0.12
|
|
15
|
+
pypdfium2>=4.30,<6
|
|
16
|
+
watchdog>=4,<7
|
|
17
|
+
psycopg[binary]>=3.2,<4
|
package/src-tauri/Cargo.lock
CHANGED
package/src-tauri/Cargo.toml
CHANGED
package/src-tauri/src/main.rs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
use std::{
|
|
2
2
|
env,
|
|
3
|
+
fs::OpenOptions,
|
|
4
|
+
path::PathBuf,
|
|
3
5
|
process::{Child, Command, Stdio},
|
|
4
6
|
sync::Mutex,
|
|
5
7
|
};
|
|
@@ -10,6 +12,7 @@ use tauri::{Manager, State};
|
|
|
10
12
|
struct BackendState {
|
|
11
13
|
origin: String,
|
|
12
14
|
command: String,
|
|
15
|
+
cwd: Option<String>,
|
|
13
16
|
child: Mutex<Option<Child>>,
|
|
14
17
|
last_error: Mutex<Option<String>>,
|
|
15
18
|
}
|
|
@@ -18,11 +21,19 @@ struct BackendState {
|
|
|
18
21
|
struct BackendStatus {
|
|
19
22
|
origin: String,
|
|
20
23
|
command: String,
|
|
24
|
+
cwd: Option<String>,
|
|
21
25
|
running: bool,
|
|
22
26
|
pid: Option<u32>,
|
|
23
27
|
last_error: Option<String>,
|
|
24
28
|
}
|
|
25
29
|
|
|
30
|
+
struct BackendLaunch {
|
|
31
|
+
command: String,
|
|
32
|
+
program: String,
|
|
33
|
+
args: Vec<String>,
|
|
34
|
+
cwd: Option<PathBuf>,
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
#[tauri::command]
|
|
27
38
|
fn backend_origin(state: State<'_, BackendState>) -> String {
|
|
28
39
|
state.origin.clone()
|
|
@@ -36,7 +47,8 @@ fn backend_status(state: State<'_, BackendState>) -> BackendStatus {
|
|
|
36
47
|
#[tauri::command]
|
|
37
48
|
fn restart_backend(state: State<'_, BackendState>) -> BackendStatus {
|
|
38
49
|
kill_backend(&state);
|
|
39
|
-
|
|
50
|
+
let launch = backend_launch(&state.origin);
|
|
51
|
+
match spawn_backend(&state.origin, &launch) {
|
|
40
52
|
Ok(child) => {
|
|
41
53
|
if let Ok(mut slot) = state.child.lock() {
|
|
42
54
|
*slot = child;
|
|
@@ -55,15 +67,174 @@ fn shutdown_backend(state: State<'_, BackendState>) -> BackendStatus {
|
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
fn split_command(command: &str) -> Vec<String> {
|
|
58
|
-
command
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
command.split_whitespace().map(|part| part.to_string()).collect()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fn command_in_path(name: &str) -> Option<String> {
|
|
74
|
+
let mut dirs: Vec<PathBuf> = env::var_os("PATH")
|
|
75
|
+
.map(|value| env::split_paths(&value).collect())
|
|
76
|
+
.unwrap_or_default();
|
|
77
|
+
dirs.extend([
|
|
78
|
+
PathBuf::from("/opt/homebrew/bin"),
|
|
79
|
+
PathBuf::from("/usr/local/bin"),
|
|
80
|
+
PathBuf::from("/usr/bin"),
|
|
81
|
+
PathBuf::from("/bin"),
|
|
82
|
+
]);
|
|
83
|
+
for dir in dirs {
|
|
84
|
+
let candidate = dir.join(name);
|
|
85
|
+
if candidate.is_file() {
|
|
86
|
+
return Some(candidate.to_string_lossy().to_string());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
None
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fn python_candidates() -> Vec<String> {
|
|
93
|
+
let mut out = Vec::new();
|
|
94
|
+
if let Ok(value) = env::var("LTCAI_PYTHON") {
|
|
95
|
+
out.push(value);
|
|
96
|
+
}
|
|
97
|
+
for name in ["python3", "python"] {
|
|
98
|
+
if let Some(path) = command_in_path(name) {
|
|
99
|
+
out.push(path);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
out.extend([
|
|
103
|
+
"/opt/homebrew/bin/python3".to_string(),
|
|
104
|
+
"/usr/local/bin/python3".to_string(),
|
|
105
|
+
"/usr/bin/python3".to_string(),
|
|
106
|
+
]);
|
|
107
|
+
out.sort();
|
|
108
|
+
out.dedup();
|
|
109
|
+
out
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fn module_importable(python: &str, module: &str) -> bool {
|
|
113
|
+
Command::new(python)
|
|
114
|
+
.args(["-c", &format!("import {module}")])
|
|
115
|
+
.stdout(Stdio::null())
|
|
116
|
+
.stderr(Stdio::null())
|
|
117
|
+
.status()
|
|
118
|
+
.map(|status| status.success())
|
|
119
|
+
.unwrap_or(false)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
fn resource_dir() -> Option<PathBuf> {
|
|
123
|
+
let exe = env::current_exe().ok()?;
|
|
124
|
+
let macos_dir = exe.parent()?;
|
|
125
|
+
let contents_dir = macos_dir.parent()?;
|
|
126
|
+
let resources = contents_dir.join("Resources");
|
|
127
|
+
if resources.exists() {
|
|
128
|
+
Some(resources)
|
|
129
|
+
} else {
|
|
130
|
+
None
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
fn bundled_python_root() -> Option<PathBuf> {
|
|
135
|
+
let resources = resource_dir()?;
|
|
136
|
+
let up = resources.join("_up_");
|
|
137
|
+
if up.join("ltcai_cli.py").is_file() {
|
|
138
|
+
Some(up)
|
|
139
|
+
} else if resources.join("ltcai_cli.py").is_file() {
|
|
140
|
+
Some(resources)
|
|
141
|
+
} else {
|
|
142
|
+
None
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
fn desktop_runtime_dir() -> Option<PathBuf> {
|
|
147
|
+
let home = env::var("HOME").ok()?;
|
|
148
|
+
let dir = PathBuf::from(home).join(".ltcai").join("desktop-runtime");
|
|
149
|
+
let _ = std::fs::create_dir_all(&dir);
|
|
150
|
+
Some(dir)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
fn python_path_env(launch: &BackendLaunch) -> Option<String> {
|
|
154
|
+
let mut paths: Vec<PathBuf> = Vec::new();
|
|
155
|
+
if let Some(resources) = bundled_python_root() {
|
|
156
|
+
paths.push(resources);
|
|
157
|
+
}
|
|
158
|
+
if let Some(cwd) = &launch.cwd {
|
|
159
|
+
if !paths.iter().any(|path| path == cwd) {
|
|
160
|
+
paths.push(cwd.clone());
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if let Some(existing) = env::var_os("PYTHONPATH") {
|
|
164
|
+
paths.extend(env::split_paths(&existing));
|
|
165
|
+
}
|
|
166
|
+
env::join_paths(paths).ok().map(|value| value.to_string_lossy().to_string())
|
|
62
167
|
}
|
|
63
168
|
|
|
64
|
-
fn
|
|
65
|
-
|
|
66
|
-
|
|
169
|
+
fn backend_launch(origin: &str) -> BackendLaunch {
|
|
170
|
+
let port = origin.rsplit(':').next().unwrap_or("8765").to_string();
|
|
171
|
+
if let Ok(command) = env::var("LATTICEAI_DESKTOP_BACKEND_CMD") {
|
|
172
|
+
let parts = split_command(&command);
|
|
173
|
+
if let Some(program) = parts.first() {
|
|
174
|
+
return BackendLaunch {
|
|
175
|
+
command,
|
|
176
|
+
program: program.clone(),
|
|
177
|
+
args: parts[1..].to_vec(),
|
|
178
|
+
cwd: env::var("LATTICEAI_DESKTOP_BACKEND_CWD").ok().map(PathBuf::from),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
for name in ["LTCAI", "ltcai"] {
|
|
184
|
+
if let Some(program) = command_in_path(name) {
|
|
185
|
+
return BackendLaunch {
|
|
186
|
+
command: format!("{program} --host 127.0.0.1 --port {port}"),
|
|
187
|
+
program,
|
|
188
|
+
args: vec!["--host".into(), "127.0.0.1".into(), "--port".into(), port],
|
|
189
|
+
cwd: None,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for python in python_candidates() {
|
|
195
|
+
if module_importable(&python, "ltcai_cli") {
|
|
196
|
+
return BackendLaunch {
|
|
197
|
+
command: format!("{python} -m ltcai_cli --host 127.0.0.1 --port {port}"),
|
|
198
|
+
program: python,
|
|
199
|
+
args: vec![
|
|
200
|
+
"-m".into(),
|
|
201
|
+
"ltcai_cli".into(),
|
|
202
|
+
"--host".into(),
|
|
203
|
+
"127.0.0.1".into(),
|
|
204
|
+
"--port".into(),
|
|
205
|
+
port,
|
|
206
|
+
],
|
|
207
|
+
cwd: None,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if let Some(resources) = bundled_python_root() {
|
|
213
|
+
let launcher = resources.join("ltcai_cli.py");
|
|
214
|
+
if launcher.is_file() {
|
|
215
|
+
if let Some(python) = python_candidates().into_iter().next() {
|
|
216
|
+
return BackendLaunch {
|
|
217
|
+
command: format!("{python} {} --host 127.0.0.1 --port {port}", launcher.display()),
|
|
218
|
+
program: python,
|
|
219
|
+
args: vec![
|
|
220
|
+
launcher.to_string_lossy().to_string(),
|
|
221
|
+
"--host".into(),
|
|
222
|
+
"127.0.0.1".into(),
|
|
223
|
+
"--port".into(),
|
|
224
|
+
port,
|
|
225
|
+
],
|
|
226
|
+
cwd: None,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
BackendLaunch {
|
|
233
|
+
command: "unavailable: LTCAI executable or importable ltcai_cli module not found".to_string(),
|
|
234
|
+
program: String::new(),
|
|
235
|
+
args: Vec::new(),
|
|
236
|
+
cwd: None,
|
|
237
|
+
}
|
|
67
238
|
}
|
|
68
239
|
|
|
69
240
|
fn set_error(state: &BackendState, err: Option<String>) {
|
|
@@ -72,30 +243,64 @@ fn set_error(state: &BackendState, err: Option<String>) {
|
|
|
72
243
|
}
|
|
73
244
|
}
|
|
74
245
|
|
|
75
|
-
fn spawn_backend(origin: &str,
|
|
246
|
+
fn spawn_backend(origin: &str, launch: &BackendLaunch) -> Result<Option<Child>, String> {
|
|
76
247
|
if env::var("LATTICEAI_DESKTOP_NO_BACKEND").is_ok() {
|
|
77
248
|
return Ok(None);
|
|
78
249
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return Err("Desktop backend command is empty.".to_string());
|
|
250
|
+
if launch.program.is_empty() {
|
|
251
|
+
return Err("Desktop backend unavailable: LTCAI executable or importable ltcai_cli module not found.".to_string());
|
|
82
252
|
}
|
|
83
|
-
|
|
84
|
-
cmd
|
|
253
|
+
|
|
254
|
+
let mut cmd = Command::new(&launch.program);
|
|
255
|
+
cmd.args(&launch.args)
|
|
85
256
|
.env("LATTICEAI_HOST", "127.0.0.1")
|
|
86
257
|
.env("LATTICEAI_PORT", origin.rsplit(':').next().unwrap_or("8765"))
|
|
87
258
|
.env("LATTICEAI_ENABLE_TELEGRAM", "false")
|
|
88
259
|
.env("LATTICEAI_AUTOLOAD_MODELS", "false")
|
|
260
|
+
.env("LATTICEAI_ALLOW_MODEL_DOWNLOADS", "false")
|
|
89
261
|
.env("LATTICEAI_CORS_ALLOW_NETWORK", "false")
|
|
262
|
+
.env("LATTICEAI_ENABLE_EXTERNAL_CONNECTORS", "false")
|
|
90
263
|
.env("LATTICEAI_TUNNEL", "false")
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
|
|
264
|
+
.env(
|
|
265
|
+
"PATH",
|
|
266
|
+
format!(
|
|
267
|
+
"{}:{}",
|
|
268
|
+
"/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin",
|
|
269
|
+
env::var("PATH").unwrap_or_default()
|
|
270
|
+
),
|
|
271
|
+
);
|
|
272
|
+
if let Some(runtime_dir) = desktop_runtime_dir() {
|
|
273
|
+
cmd.env("LATTICEAI_AGENT_ROOT", runtime_dir.join("agent_workspace"));
|
|
274
|
+
if launch.cwd.is_none() {
|
|
275
|
+
cmd.current_dir(&runtime_dir);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if let Some(python_path) = python_path_env(launch) {
|
|
279
|
+
cmd.env("PYTHONPATH", python_path);
|
|
280
|
+
}
|
|
281
|
+
if let Some(cwd) = &launch.cwd {
|
|
94
282
|
cmd.current_dir(cwd);
|
|
95
283
|
}
|
|
284
|
+
if let Ok(home) = env::var("HOME") {
|
|
285
|
+
let log_dir = PathBuf::from(home).join(".ltcai");
|
|
286
|
+
let _ = std::fs::create_dir_all(&log_dir);
|
|
287
|
+
if let Ok(file) = OpenOptions::new().create(true).append(true).open(log_dir.join("desktop-sidecar.log")) {
|
|
288
|
+
cmd.stdout(Stdio::from(file));
|
|
289
|
+
} else {
|
|
290
|
+
cmd.stdout(Stdio::null());
|
|
291
|
+
}
|
|
292
|
+
if let Ok(file) = OpenOptions::new().create(true).append(true).open(log_dir.join("desktop-sidecar.err.log")) {
|
|
293
|
+
cmd.stderr(Stdio::from(file));
|
|
294
|
+
} else {
|
|
295
|
+
cmd.stderr(Stdio::null());
|
|
296
|
+
}
|
|
297
|
+
} else {
|
|
298
|
+
cmd.stdout(Stdio::null()).stderr(Stdio::null());
|
|
299
|
+
}
|
|
300
|
+
|
|
96
301
|
cmd.spawn()
|
|
97
302
|
.map(Some)
|
|
98
|
-
.map_err(|err| format!("Failed to start desktop backend '{}': {}",
|
|
303
|
+
.map_err(|err| format!("Failed to start desktop backend '{}': {}", launch.command, err))
|
|
99
304
|
}
|
|
100
305
|
|
|
101
306
|
fn kill_backend(state: &BackendState) {
|
|
@@ -125,25 +330,40 @@ fn status_from_state(state: &BackendState) -> BackendStatus {
|
|
|
125
330
|
}
|
|
126
331
|
}
|
|
127
332
|
}
|
|
128
|
-
let last_error = state
|
|
129
|
-
.last_error
|
|
130
|
-
.lock()
|
|
131
|
-
.ok()
|
|
132
|
-
.and_then(|guard| guard.clone());
|
|
333
|
+
let last_error = state.last_error.lock().ok().and_then(|guard| guard.clone());
|
|
133
334
|
BackendStatus {
|
|
134
335
|
origin: state.origin.clone(),
|
|
135
336
|
command: state.command.clone(),
|
|
337
|
+
cwd: state.cwd.clone(),
|
|
136
338
|
running,
|
|
137
339
|
pid,
|
|
138
340
|
last_error,
|
|
139
341
|
}
|
|
140
342
|
}
|
|
141
343
|
|
|
344
|
+
fn wait_for_backend(origin: &str) {
|
|
345
|
+
let host_port = origin
|
|
346
|
+
.trim_start_matches("http://")
|
|
347
|
+
.trim_start_matches("https://")
|
|
348
|
+
.split('/')
|
|
349
|
+
.next()
|
|
350
|
+
.unwrap_or("127.0.0.1:8765")
|
|
351
|
+
.to_string();
|
|
352
|
+
for _ in 0..45 {
|
|
353
|
+
if std::net::TcpStream::connect(&host_port).is_ok() {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
std::thread::sleep(std::time::Duration::from_millis(500));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
142
360
|
fn main() {
|
|
143
361
|
let origin = env::var("LATTICEAI_DESKTOP_BACKEND_ORIGIN")
|
|
144
362
|
.unwrap_or_else(|_| "http://127.0.0.1:8765".to_string());
|
|
145
|
-
let
|
|
146
|
-
let
|
|
363
|
+
let launch = backend_launch(&origin);
|
|
364
|
+
let command = launch.command.clone();
|
|
365
|
+
let cwd = launch.cwd.as_ref().map(|path| path.to_string_lossy().to_string());
|
|
366
|
+
let (child, last_error) = match spawn_backend(&origin, &launch) {
|
|
147
367
|
Ok(child) => (child, None),
|
|
148
368
|
Err(err) => (None, Some(err)),
|
|
149
369
|
};
|
|
@@ -151,6 +371,7 @@ fn main() {
|
|
|
151
371
|
.manage(BackendState {
|
|
152
372
|
origin,
|
|
153
373
|
command,
|
|
374
|
+
cwd,
|
|
154
375
|
child: Mutex::new(child),
|
|
155
376
|
last_error: Mutex::new(last_error),
|
|
156
377
|
})
|
|
@@ -163,6 +384,17 @@ fn main() {
|
|
|
163
384
|
.setup(|app| {
|
|
164
385
|
if let Some(window) = app.get_webview_window("main") {
|
|
165
386
|
let _ = window.set_title("Lattice AI");
|
|
387
|
+
let _ = window.show();
|
|
388
|
+
let _ = window.set_focus();
|
|
389
|
+
let origin = app.state::<BackendState>().origin.clone();
|
|
390
|
+
let target = format!("{}/app", origin.trim_end_matches('/'));
|
|
391
|
+
let mut window_for_nav = window.clone();
|
|
392
|
+
std::thread::spawn(move || {
|
|
393
|
+
wait_for_backend(&origin);
|
|
394
|
+
if let Ok(url) = tauri::Url::parse(&target) {
|
|
395
|
+
let _ = window_for_nav.navigate(url);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
166
398
|
}
|
|
167
399
|
Ok(())
|
|
168
400
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://schema.tauri.app/config/2",
|
|
3
3
|
"productName": "Lattice AI",
|
|
4
|
-
"version": "4.3.
|
|
4
|
+
"version": "4.3.1",
|
|
5
5
|
"identifier": "ai.lattice.desktop",
|
|
6
6
|
"build": {
|
|
7
7
|
"beforeDevCommand": "npm run frontend:dev",
|
|
@@ -31,6 +31,25 @@
|
|
|
31
31
|
"dmg",
|
|
32
32
|
"app"
|
|
33
33
|
],
|
|
34
|
+
"resources": [
|
|
35
|
+
"../auto_setup.py",
|
|
36
|
+
"../kg_schema.py",
|
|
37
|
+
"../knowledge_graph.py",
|
|
38
|
+
"../knowledge_graph_api.py",
|
|
39
|
+
"../llm_router.py",
|
|
40
|
+
"../local_knowledge_api.py",
|
|
41
|
+
"../ltcai_cli.py",
|
|
42
|
+
"../mcp_registry.py",
|
|
43
|
+
"../p_reinforce.py",
|
|
44
|
+
"../server.py",
|
|
45
|
+
"../setup_wizard.py",
|
|
46
|
+
"../telegram_bot.py",
|
|
47
|
+
"../requirements.txt",
|
|
48
|
+
"../latticeai",
|
|
49
|
+
"../lattice_brain",
|
|
50
|
+
"../tools",
|
|
51
|
+
"../static"
|
|
52
|
+
],
|
|
34
53
|
"icon": [
|
|
35
54
|
"../static/icons/icon-192.png",
|
|
36
55
|
"../static/icons/icon-512.png"
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.3.
|
|
2
|
+
"version": "4.3.1",
|
|
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-
|
|
9
|
+
"index.html": "/static/app/assets/index-BhPuj8rT.js",
|
|
10
10
|
"assets/index-yZswHE3d.css": "/static/app/assets/index-yZswHE3d.css"
|
|
11
11
|
},
|
|
12
12
|
"vite": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"isDynamicEntry": true
|
|
18
18
|
},
|
|
19
19
|
"index.html": {
|
|
20
|
-
"file": "assets/index-
|
|
20
|
+
"file": "assets/index-BhPuj8rT.js",
|
|
21
21
|
"name": "index",
|
|
22
22
|
"src": "index.html",
|
|
23
23
|
"isEntry": true,
|