ltcai 8.6.0 → 8.7.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.
- package/README.md +31 -29
- package/docs/CHANGELOG.md +23 -1
- package/docs/COMMUNITY_AND_PLUGINS.md +5 -3
- package/docs/DEVELOPMENT.md +11 -9
- package/docs/LEGACY_COMPATIBILITY.md +3 -3
- package/docs/ONBOARDING.md +2 -2
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +2 -2
- package/docs/kg-schema.md +1 -1
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/app_factory.py +2 -2
- package/latticeai/core/config.py +14 -2
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/latticeai/models/router.py +3 -2
- package/latticeai/runtime/router_registration.py +11 -5
- package/latticeai/services/architecture_readiness.py +2 -2
- package/latticeai/services/model_runtime.py +52 -28
- package/latticeai/services/product_readiness.py +11 -11
- package/package.json +3 -2
- package/scripts/bump_version.py +2 -0
- package/scripts/check_python.py +25 -12
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/tauri.conf.json +1 -1
- package/static/app/asset-manifest.json +10 -10
- package/static/app/assets/{Act-IrojDEWY.js → Act-_U7mhXir.js} +1 -1
- package/static/app/assets/{Brain--VODO4HM.js → Brain-BxyTHZ21.js} +1 -1
- package/static/app/assets/Capture-DyDKWNh9.js +1 -0
- package/static/app/assets/{Library-DrVto3cO.js → Library-DJ8KioFM.js} +1 -1
- package/static/app/assets/{System-DNrVbcMX.js → System-C0FIb3OO.js} +1 -1
- package/static/app/assets/index-Bh7IIlyY.js +16 -0
- package/static/app/assets/{primitives-lz45ZfWY.js → primitives-BywkNS3f.js} +1 -1
- package/static/app/assets/{textarea-C7uwJsxy.js → textarea-CQ61Rycp.js} +1 -1
- package/static/app/index.html +1 -1
- package/static/sw.js +1 -1
- package/static/app/assets/Capture-BUP_wJ7s.js +0 -1
- package/static/app/assets/index-BaaPtsLp.js +0 -16
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI
|
|
2
2
|
|
|
3
|
-
**Lattice AI 8.
|
|
3
|
+
**Lattice AI 8.7.0 is the local-first Digital Brain platform. This release hardens runtime state ownership, refreshes the checked-in release evidence, and synchronizes package, desktop, extension, and documentation metadata to the 8.7.0 line.**
|
|
4
4
|
|
|
5
5
|
**Lattice AI는 모델이 바뀌어도 내 지식과 맥락을 보존하는 로컬 우선 AI 브레인입니다.**
|
|
6
6
|
|
|
@@ -65,9 +65,9 @@ You need Lattice AI when:
|
|
|
65
65
|
## Living Brain Flow
|
|
66
66
|
|
|
67
67
|
The screenshots below are the latest checked-in visual evidence captures from
|
|
68
|
-
the 8.
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
the 8.7.0 release. They keep the first-run Brain flow, memory graph, source
|
|
69
|
+
capture, model library, system view, admin console, and review center visible as
|
|
70
|
+
release gates.
|
|
71
71
|
|
|
72
72
|
### 1. Wake Brain
|
|
73
73
|
|
|
@@ -79,21 +79,21 @@ confirm owner, check the computer, choose the Brain voice.
|
|
|
79
79
|
Choose the owner of the Brain. The profile is not a SaaS account by default; it
|
|
80
80
|
is the local identity for the knowledge you keep.
|
|
81
81
|
|
|
82
|
-

|
|
83
83
|
|
|
84
84
|
### 3. Recommended Models
|
|
85
85
|
|
|
86
86
|
Start with a short list: safest recommendation, faster model, stronger model.
|
|
87
87
|
Advanced details stay available without overwhelming first-time users.
|
|
88
88
|
|
|
89
|
-

|
|
90
90
|
|
|
91
91
|
### 4. Install And Load
|
|
92
92
|
|
|
93
93
|
Download and load only after consent. Lattice explains model size, local
|
|
94
94
|
execution, and network use before work starts.
|
|
95
95
|
|
|
96
|
-

|
|
97
97
|
|
|
98
98
|
### 5. Brain Chat
|
|
99
99
|
|
|
@@ -101,14 +101,14 @@ Talk normally. Useful decisions and context become memory, then appear later as
|
|
|
101
101
|
topics, relationships, graph structure, and the concentric memory rings around
|
|
102
102
|
the Brain.
|
|
103
103
|
|
|
104
|
-

|
|
105
105
|
|
|
106
106
|
### 6. Review Center
|
|
107
107
|
|
|
108
108
|
Automation results are staged for review before they become durable decisions.
|
|
109
109
|
Snooze, unsnooze, run now, approve, and dismiss actions stay explicit.
|
|
110
110
|
|
|
111
|
-

|
|
112
112
|
|
|
113
113
|
## Brain Depths
|
|
114
114
|
|
|
@@ -124,10 +124,10 @@ The user travels inward from everyday memory to deeper structure:
|
|
|
124
124
|
|
|
125
125
|
Walkthrough:
|
|
126
126
|
|
|
127
|
-

|
|
128
128
|
|
|
129
129
|
Screenshot index and capture notes:
|
|
130
|
-
[output/release/v8.
|
|
130
|
+
[output/release/v8.7.0/SCREENSHOT_INDEX.md](output/release/v8.7.0/SCREENSHOT_INDEX.md)
|
|
131
131
|
|
|
132
132
|
## Install
|
|
133
133
|
|
|
@@ -190,7 +190,6 @@ Main validation set:
|
|
|
190
190
|
|
|
191
191
|
```bash
|
|
192
192
|
npm run check:python
|
|
193
|
-
node scripts/run_python.mjs -m ruff check .
|
|
194
193
|
npm run lint
|
|
195
194
|
npm run typecheck
|
|
196
195
|
npm run test:unit
|
|
@@ -200,34 +199,36 @@ npm run desktop:tauri:check
|
|
|
200
199
|
npm run docs:check-links
|
|
201
200
|
```
|
|
202
201
|
|
|
202
|
+
`npm run lint` includes the Python Ruff baseline, frontend TypeScript lint
|
|
203
|
+
gate, visual smoke syntax checks, and i18n literal checks.
|
|
204
|
+
|
|
203
205
|
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for developer workflow details.
|
|
204
206
|
|
|
205
207
|
## Current Release
|
|
206
208
|
|
|
207
|
-
The current release is **8.
|
|
209
|
+
The current release is **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**:
|
|
208
210
|
|
|
209
|
-
-
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
|
|
213
|
-
-
|
|
214
|
-
|
|
215
|
-
- The
|
|
216
|
-
|
|
217
|
-
hardening remains active.
|
|
211
|
+
- Internal model-runtime logic now reads from the typed `ModelRuntimeState`
|
|
212
|
+
object instead of the legacy module-global compatibility surface.
|
|
213
|
+
- `sync_to_module_globals()` remains available for external shims, but now emits
|
|
214
|
+
a `DeprecationWarning` so new code does not rebuild global-state coupling.
|
|
215
|
+
- The 8.7.0 release evidence refresh updates screenshots, walkthrough GIF/WebM,
|
|
216
|
+
package/runtime/static/Tauri metadata, and current-release documentation.
|
|
217
|
+
- The 8.6 desktop Capture reliability and 8.5 ToolRegistry/Config DI hardening
|
|
218
|
+
remain active release guarantees.
|
|
218
219
|
|
|
219
|
-
Expected artifacts for 8.
|
|
220
|
+
Expected artifacts for 8.7.0 release must use exact filenames:
|
|
220
221
|
|
|
221
|
-
- `dist/ltcai-8.
|
|
222
|
-
- `dist/ltcai-8.
|
|
223
|
-
- `ltcai-8.
|
|
224
|
-
- `dist/ltcai-8.
|
|
225
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.
|
|
222
|
+
- `dist/ltcai-8.7.0-py3-none-any.whl`
|
|
223
|
+
- `dist/ltcai-8.7.0.tar.gz`
|
|
224
|
+
- `ltcai-8.7.0.tgz`
|
|
225
|
+
- `dist/ltcai-8.7.0.vsix`
|
|
226
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.7.0_aarch64.dmg`
|
|
226
227
|
|
|
227
228
|
Do not use wildcard artifact uploads. Package registry publishing remains owner-run.
|
|
228
229
|
|
|
229
230
|
See [docs/ROADMAP_RECOMMENDATIONS.md](docs/ROADMAP_RECOMMENDATIONS.md) for the
|
|
230
|
-
strategic roadmap slices applied through 8.
|
|
231
|
+
strategic roadmap slices applied through 8.7.0 and the follow-up tracks.
|
|
231
232
|
|
|
232
233
|
## Known Limitations
|
|
233
234
|
|
|
@@ -244,6 +245,7 @@ strategic roadmap slices applied through 8.6.0 and the follow-up tracks.
|
|
|
244
245
|
|
|
245
246
|
| Version | Theme |
|
|
246
247
|
| --- | --- |
|
|
248
|
+
| 8.7.0 | Runtime State Hygiene & Release Evidence Refresh: model-runtime internals prefer typed state over legacy globals, compatibility sync is deprecated, 8.7.0 visual evidence is refreshed, and all release metadata/docs are synchronized |
|
|
247
249
|
| 8.6.0 | Desktop Capture & Navigation Reliability: native folder selection works from the Tauri localhost app, picker failures surface in Capture, web saving remains one-action, and the Brain shell sidebar/admin flow is CI-covered |
|
|
248
250
|
| 8.5.0 | Tool Registry Readiness & Config DI: ToolRegistry drift removed, `tz_name` flows through central Config into automation runtimes, and current-release documentation is synchronized |
|
|
249
251
|
| 8.4.0 | Action-Aware Brain Chat: explicit file create/write/save/edit requests from Brain Chat route into the governed workspace file tool so files are actually created instead of returned as code-only answers |
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,29 @@ existed at that release.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## [8.7.0] - 2026-07-05
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Added unit test coverage for model-runtime `STATE` source-of-truth behavior
|
|
13
|
+
and deprecation warnings on legacy global synchronization.
|
|
14
|
+
- Added refreshed 8.7.0 screenshots, walkthrough GIF/WebM, and capture notes
|
|
15
|
+
under `output/release/v8.7.0/`.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Reduced internal reliance on bare module globals in
|
|
19
|
+
`latticeai/services/model_runtime.py`; implementation logic now consistently
|
|
20
|
+
reads from the `ModelRuntimeState` instance while globals remain as a legacy
|
|
21
|
+
compatibility surface.
|
|
22
|
+
- Added `DeprecationWarning` to `sync_to_module_globals()` while preserving the
|
|
23
|
+
external shim behavior.
|
|
24
|
+
- Removed a loose `as any` cast from `frontend/src/pages/Act.tsx`.
|
|
25
|
+
- Version bumped to 8.7.0 across Python, npm, VS Code extension, Tauri, static
|
|
26
|
+
metadata, README evidence links, release notes, and current-release
|
|
27
|
+
documentation.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- Internal model-runtime functions now prefer the typed state object per the
|
|
31
|
+
project preference for composition over global mutable state.
|
|
10
32
|
|
|
11
33
|
## [8.6.0] - 2026-07-05
|
|
12
34
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Community And Plugins
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**.
|
|
4
4
|
|
|
5
|
-
LatticeAI defines the path from a strong local-first framework (8.4.0
|
|
6
|
-
|
|
5
|
+
LatticeAI defines the path from a strong local-first framework (8.4.0
|
|
6
|
+
action-aware baseline, 8.5.0 registry+DI hardening, 8.6.0 capture/navigation
|
|
7
|
+
reliability, and 8.7.0 runtime-state hygiene) to a product ecosystem. The
|
|
8
|
+
immediate goal is small and practical: make it clear how
|
|
7
9
|
contributors can extend the Brain without weakening local-first trust,
|
|
8
10
|
workspace scoping, or release quality.
|
|
9
11
|
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Lattice AI Development
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**.
|
|
4
4
|
|
|
5
5
|
This document is for contributors working on the local-first Digital Brain
|
|
6
6
|
codebase. Product positioning and quick start stay in `README.md`; release
|
|
7
|
-
history is intentionally limited to 7.0.0-8.
|
|
7
|
+
history is intentionally limited to 7.0.0-8.7.0 in `docs/CHANGELOG.md` and
|
|
8
8
|
`RELEASE.md`.
|
|
9
9
|
|
|
10
10
|
## Product Contract
|
|
@@ -49,13 +49,15 @@ API, UI, or release work, run:
|
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
npm run check:python
|
|
52
|
-
node scripts/run_python.mjs -m ruff check .
|
|
53
52
|
npm run lint
|
|
54
53
|
npm run typecheck
|
|
55
54
|
npm run test:unit
|
|
56
55
|
npm run docs:check-links
|
|
57
56
|
```
|
|
58
57
|
|
|
58
|
+
`npm run lint` runs the Python Ruff baseline, frontend TypeScript lint gate,
|
|
59
|
+
visual smoke syntax checks, and i18n literal checks.
|
|
60
|
+
|
|
59
61
|
Use these when the change touches the relevant surface:
|
|
60
62
|
|
|
61
63
|
```bash
|
|
@@ -112,10 +114,10 @@ For user-facing, API, runtime, release, or packaging changes, check:
|
|
|
112
114
|
Release/publish examples must use exact target-version filenames. Do not
|
|
113
115
|
document wildcard artifact upload commands.
|
|
114
116
|
|
|
115
|
-
For 8.
|
|
117
|
+
For 8.7.0 release work, exact artifacts are:
|
|
116
118
|
|
|
117
|
-
- `dist/ltcai-8.
|
|
118
|
-
- `dist/ltcai-8.
|
|
119
|
-
- `ltcai-8.
|
|
120
|
-
- `dist/ltcai-8.
|
|
121
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.
|
|
119
|
+
- `dist/ltcai-8.7.0-py3-none-any.whl`
|
|
120
|
+
- `dist/ltcai-8.7.0.tar.gz`
|
|
121
|
+
- `ltcai-8.7.0.tgz`
|
|
122
|
+
- `dist/ltcai-8.7.0.vsix`
|
|
123
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.7.0_aarch64.dmg`
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Legacy Compatibility Map
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**.
|
|
4
4
|
|
|
5
5
|
Lattice AI is moving toward a smaller, modular architecture centered on
|
|
6
6
|
`lattice_brain`, `latticeai.services`, `latticeai.api`, and `latticeai.runtime`.
|
|
7
7
|
Some root-level modules remain packaged for compatibility with older imports,
|
|
8
8
|
CLI entrypoints, or extension workflows. Their presence does not define the
|
|
9
|
-
current 8.
|
|
9
|
+
current 8.7.0 architecture.
|
|
10
10
|
|
|
11
|
-
8.
|
|
11
|
+
8.7.0 also tracks the inner compatibility layers that sit below the root
|
|
12
12
|
modules. The managed inventory lives in `latticeai.core.legacy_compatibility`
|
|
13
13
|
and groups shims by layer:
|
|
14
14
|
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI Onboarding
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**.
|
|
4
4
|
|
|
5
5
|
The first-run goal is a five-minute path from "I opened the app" to "my Brain
|
|
6
6
|
has a source, a question, and proof." This page is the product contract behind
|
|
@@ -32,7 +32,7 @@ read the docs first.
|
|
|
32
32
|
|
|
33
33
|
## Release Gate
|
|
34
34
|
|
|
35
|
-
8.
|
|
35
|
+
8.7.0 treats onboarding as a release gate, not marketing copy. The current
|
|
36
36
|
machine-checkable product readiness report requires this five-minute contract,
|
|
37
37
|
the Brain Home surface, setup helpers, graph ingestion tests, and exact release
|
|
38
38
|
artifact documentation before the release can be called complete.
|
package/docs/TRUST_MODEL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI Trust Model
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**.
|
|
4
4
|
|
|
5
5
|
Lattice AI is local-first, explicit about external communication, and honest
|
|
6
6
|
when a capability is unavailable.
|
package/docs/WHY_LATTICE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Why Lattice AI Exists
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.7.0 — Runtime State Hygiene & Release Evidence Refresh**.
|
|
4
4
|
|
|
5
5
|
**Lattice AI is a local-first Digital Brain that keeps your knowledge durable
|
|
6
6
|
across any AI model.**
|
|
@@ -32,7 +32,7 @@ The graph matters, but it is not the product identity. The product identity is a
|
|
|
32
32
|
local-first Digital Brain: a place where the user can talk, add sources, watch
|
|
33
33
|
memory grow, and inspect the Knowledge Graph when they need proof.
|
|
34
34
|
|
|
35
|
-
In 8.
|
|
35
|
+
In 8.7.0 the first screen is intentionally not a dashboard. The living Brain,
|
|
36
36
|
conversation composer, evidence-backed Brain Brief, and five-minute onboarding
|
|
37
37
|
path appear together so the user immediately knows what matters, what to add,
|
|
38
38
|
and why the answer is grounded in local memory.
|
package/docs/kg-schema.md
CHANGED
|
@@ -21,7 +21,7 @@ from typing import Any, Callable, Dict, List, Optional
|
|
|
21
21
|
from .contracts import multi_agent_contract
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
MULTI_AGENT_VERSION = "8.
|
|
24
|
+
MULTI_AGENT_VERSION = "8.7.0"
|
|
25
25
|
|
|
26
26
|
AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
|
|
27
27
|
CORE_PIPELINE = ("planner", "executor", "reviewer")
|
package/latticeai/__init__.py
CHANGED
package/latticeai/app_factory.py
CHANGED
|
@@ -107,7 +107,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
|
|
|
107
107
|
enforce_rate_limit as _enforce_rate_limit,
|
|
108
108
|
)
|
|
109
109
|
from latticeai.core.audit import (
|
|
110
|
-
get_audit_log as _get_audit_log,
|
|
110
|
+
get_audit_log as _get_audit_log, # noqa: F401 - legacy server_app attr exported via locals()
|
|
111
111
|
classify_sensitive_message as _classify_sensitive_message,
|
|
112
112
|
build_sensitivity_report as _build_sensitivity_report,
|
|
113
113
|
build_admin_audit_report as _build_admin_audit_report,
|
|
@@ -992,7 +992,7 @@ def _build(config: "Optional[Config]" = None) -> Dict[str, Any]:
|
|
|
992
992
|
create_admin_router=create_admin_router,
|
|
993
993
|
require_admin=require_admin,
|
|
994
994
|
get_history=get_history,
|
|
995
|
-
get_audit_log=
|
|
995
|
+
get_audit_log=get_audit_log,
|
|
996
996
|
audit_file=AUDIT_FILE,
|
|
997
997
|
public_user=public_user,
|
|
998
998
|
load_vpc_config=load_vpc_config,
|
package/latticeai/core/config.py
CHANGED
|
@@ -43,7 +43,12 @@ def _bool(env: Mapping[str, str], key: str, default: bool = False) -> bool:
|
|
|
43
43
|
raw = env.get(key)
|
|
44
44
|
if raw is None:
|
|
45
45
|
return default
|
|
46
|
-
|
|
46
|
+
normalized = raw.strip().lower()
|
|
47
|
+
if normalized in {"1", "true", "yes", "on"}:
|
|
48
|
+
return True
|
|
49
|
+
if normalized in {"0", "false", "no", "off"}:
|
|
50
|
+
return False
|
|
51
|
+
return default
|
|
47
52
|
|
|
48
53
|
|
|
49
54
|
def _int(env: Mapping[str, str], key: str, default: int) -> int:
|
|
@@ -56,6 +61,13 @@ def _int(env: Mapping[str, str], key: str, default: int) -> int:
|
|
|
56
61
|
return default
|
|
57
62
|
|
|
58
63
|
|
|
64
|
+
def _port(env: Mapping[str, str], key: str, default: int) -> int:
|
|
65
|
+
port = _int(env, key, default)
|
|
66
|
+
if 1 <= port <= 65535:
|
|
67
|
+
return port
|
|
68
|
+
return default
|
|
69
|
+
|
|
70
|
+
|
|
59
71
|
@dataclass(frozen=True)
|
|
60
72
|
class Config:
|
|
61
73
|
"""Everything a caller must know about app-level settings.
|
|
@@ -146,7 +158,7 @@ class Config:
|
|
|
146
158
|
is_public = app_mode == "public"
|
|
147
159
|
|
|
148
160
|
host = _value(env, "LATTICEAI_HOST", "127.0.0.1")
|
|
149
|
-
port =
|
|
161
|
+
port = _port(env, "LATTICEAI_PORT", 4825)
|
|
150
162
|
network_exposed = not host_is_loopback(host)
|
|
151
163
|
|
|
152
164
|
cors_extra = [item.strip() for item in _value(env, "LATTICEAI_CORS_ALLOWED_ORIGINS", "").split(",") if item.strip()]
|
|
@@ -49,7 +49,7 @@ __all__ = [
|
|
|
49
49
|
"remove_skill_directory",
|
|
50
50
|
]
|
|
51
51
|
|
|
52
|
-
WORKSPACE_OS_VERSION = "8.
|
|
52
|
+
WORKSPACE_OS_VERSION = "8.7.0"
|
|
53
53
|
|
|
54
54
|
# Workspace types separate single-user Personal workspaces from shared
|
|
55
55
|
# Organization workspaces. Both keep the same local-first JSON store; the type
|
|
@@ -13,8 +13,9 @@ import time
|
|
|
13
13
|
from dataclasses import dataclass
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
-
#
|
|
17
|
-
|
|
16
|
+
# Default Gemma 4 assistant drafting to MTP without overriding an operator's
|
|
17
|
+
# explicit MLX runtime choice.
|
|
18
|
+
os.environ.setdefault("MLX_VLM_DRAFT_KIND", "mtp")
|
|
18
19
|
|
|
19
20
|
from concurrent.futures import ThreadPoolExecutor
|
|
20
21
|
from typing import AsyncIterator, Dict, Optional, Tuple, List
|
|
@@ -162,16 +162,22 @@ def build_auth_admin_security_router_bundle(
|
|
|
162
162
|
append_audit_event=append_audit_event,
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
-
def
|
|
165
|
+
def audit_log_events_safe() -> list[dict[str, Any]]:
|
|
166
166
|
try:
|
|
167
|
-
return get_audit_log(
|
|
167
|
+
return get_audit_log()
|
|
168
|
+
except TypeError:
|
|
169
|
+
try:
|
|
170
|
+
return get_audit_log(audit_file)
|
|
171
|
+
except Exception as exc: # pragma: no cover - defensive legacy behavior
|
|
172
|
+
logger.warning("security audit events load failed: %s", exc)
|
|
173
|
+
return []
|
|
168
174
|
except Exception as exc: # pragma: no cover - defensive legacy behavior
|
|
169
175
|
logger.warning("security audit events load failed: %s", exc)
|
|
170
176
|
return []
|
|
171
177
|
|
|
172
178
|
def security_list_uploaded_files() -> list[dict[str, Any]]:
|
|
173
179
|
files: list[dict[str, Any]] = []
|
|
174
|
-
for idx, event in enumerate(
|
|
180
|
+
for idx, event in enumerate(audit_log_events_safe()):
|
|
175
181
|
if event.get("event_type") != "document_upload":
|
|
176
182
|
continue
|
|
177
183
|
files.append({
|
|
@@ -191,7 +197,7 @@ def build_auth_admin_security_router_bundle(
|
|
|
191
197
|
security_router = create_security_router(
|
|
192
198
|
require_admin=require_admin,
|
|
193
199
|
get_history=get_history,
|
|
194
|
-
get_audit_events=
|
|
200
|
+
get_audit_events=audit_log_events_safe,
|
|
195
201
|
classify_sensitive_message=classify_sensitive_message,
|
|
196
202
|
build_sensitivity_report=build_sensitivity_report,
|
|
197
203
|
list_uploaded_files=security_list_uploaded_files,
|
|
@@ -205,7 +211,7 @@ def build_auth_admin_security_router_bundle(
|
|
|
205
211
|
"security_router": security_router,
|
|
206
212
|
"_graph_stats_safe": graph_stats_safe,
|
|
207
213
|
"_product_hardening_status": product_hardening_status,
|
|
208
|
-
"_security_audit_events_safe":
|
|
214
|
+
"_security_audit_events_safe": audit_log_events_safe,
|
|
209
215
|
"_security_list_uploaded_files": security_list_uploaded_files,
|
|
210
216
|
}
|
|
211
217
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Machine-checkable architecture readiness gates for release work.
|
|
2
2
|
|
|
3
|
-
8.
|
|
3
|
+
8.7.0 keeps the major architecture priorities under an explicit release
|
|
4
4
|
contract while product maturity work reduces visible beta seams. AgentRuntime, ToolRegistry,
|
|
5
5
|
central Config, decomposed server runtime, and Knowledge Graph stabilization
|
|
6
6
|
must remain discoverable, ordered, and backed by tests before the release can be
|
|
@@ -17,7 +17,7 @@ from typing import Any, Dict, List
|
|
|
17
17
|
from latticeai.core.legacy_compatibility import legacy_shim_report
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
ARCHITECTURE_VERSION_TARGET = "8.
|
|
20
|
+
ARCHITECTURE_VERSION_TARGET = "8.7.0"
|
|
21
21
|
|
|
22
22
|
PREFERRED_REFACTORING_ORDER = [
|
|
23
23
|
"agent-runtime",
|
|
@@ -16,6 +16,7 @@ import shutil
|
|
|
16
16
|
import time
|
|
17
17
|
import urllib.error
|
|
18
18
|
import urllib.request
|
|
19
|
+
import warnings
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
from typing import AsyncIterator, Dict, List, Optional
|
|
21
22
|
|
|
@@ -100,6 +101,21 @@ class ModelRuntimeState:
|
|
|
100
101
|
self.get_user_api_key = _missing_user_api_key
|
|
101
102
|
|
|
102
103
|
def sync_to_module_globals(self):
|
|
104
|
+
"""Sync to bare module globals for legacy external importers.
|
|
105
|
+
|
|
106
|
+
This is a compatibility surface only. Internal code should use STATE.
|
|
107
|
+
Emits DeprecationWarning (future removal in major after 8.x).
|
|
108
|
+
"""
|
|
109
|
+
warnings.warn(
|
|
110
|
+
"sync_to_module_globals is a legacy compatibility shim and will be removed "
|
|
111
|
+
"after 8.x. Use latticeai.services.model_runtime.STATE or injected context instead.",
|
|
112
|
+
DeprecationWarning,
|
|
113
|
+
stacklevel=2,
|
|
114
|
+
)
|
|
115
|
+
self._sync_globals()
|
|
116
|
+
|
|
117
|
+
def _sync_globals(self) -> None:
|
|
118
|
+
"""Internal no-warning sync used at init."""
|
|
103
119
|
global router, APP_MODE, DEFAULT_HOST, DEFAULT_PORT, DATA_DIR, BASE_DIR
|
|
104
120
|
global ENABLE_TELEGRAM, ENABLE_GRAPH, AUTOLOAD_MODELS, MODEL_IDLE_UNLOAD_SECONDS
|
|
105
121
|
global ALLOW_LOCAL_MODELS, REQUIRE_AUTH, INVITE_GATE_ENABLED, ALLOW_PLAINTEXT_API_KEYS
|
|
@@ -128,7 +144,7 @@ class ModelRuntimeState:
|
|
|
128
144
|
get_user_api_key = self.get_user_api_key
|
|
129
145
|
|
|
130
146
|
STATE = ModelRuntimeState()
|
|
131
|
-
STATE.
|
|
147
|
+
STATE._sync_globals() # initial no-warning; public API warns on explicit legacy syncs
|
|
132
148
|
|
|
133
149
|
# Configured by server_app.configure_model_runtime during app assembly.
|
|
134
150
|
|
|
@@ -141,7 +157,9 @@ def _env_bool(key: str, default: bool = False) -> bool:
|
|
|
141
157
|
|
|
142
158
|
|
|
143
159
|
def _download_allowed(allow_download: bool = False) -> bool:
|
|
144
|
-
|
|
160
|
+
# Prefer STATE (the source of truth) over bare module global for internal logic.
|
|
161
|
+
autoload = getattr(STATE, "AUTOLOAD_MODELS", AUTOLOAD_MODELS)
|
|
162
|
+
return bool(allow_download) or _env_bool("LATTICEAI_ALLOW_MODEL_DOWNLOADS", default=False) or bool(autoload)
|
|
145
163
|
|
|
146
164
|
|
|
147
165
|
def _download_block(provider: str, model_name: str) -> None:
|
|
@@ -204,7 +222,7 @@ def configure_model_runtime(**deps) -> None:
|
|
|
204
222
|
elif key == "get_user_api_key":
|
|
205
223
|
STATE.get_user_api_key = value
|
|
206
224
|
|
|
207
|
-
STATE.
|
|
225
|
+
STATE._sync_globals() # wiring path uses internal (no spurious deprecation in normal startup)
|
|
208
226
|
|
|
209
227
|
|
|
210
228
|
# Catalog data + version-dedup helpers live in ``model_catalog``; re-exported
|
|
@@ -727,7 +745,8 @@ def engine_installed(engine: str) -> bool:
|
|
|
727
745
|
return False
|
|
728
746
|
|
|
729
747
|
def engine_status() -> List[Dict]:
|
|
730
|
-
|
|
748
|
+
r = getattr(STATE, "router", None) or router
|
|
749
|
+
cloud_models = r.detected_cloud_models() if r else []
|
|
731
750
|
cloud_by_provider = {}
|
|
732
751
|
for model in cloud_models:
|
|
733
752
|
cloud_by_provider.setdefault(model["provider"], []).append(model)
|
|
@@ -887,37 +906,41 @@ def engine_status() -> List[Dict]:
|
|
|
887
906
|
return engines
|
|
888
907
|
|
|
889
908
|
def runtime_features() -> Dict:
|
|
909
|
+
# Read from STATE object (central) for implementation; bare globals kept only
|
|
910
|
+
# for external legacy consumers who import names directly from this module.
|
|
911
|
+
s = STATE
|
|
912
|
+
r = getattr(s, "router", None) or router
|
|
890
913
|
return {
|
|
891
|
-
"mode": APP_MODE,
|
|
892
|
-
"public": IS_PUBLIC_MODE,
|
|
893
|
-
"host": DEFAULT_HOST,
|
|
894
|
-
"port": DEFAULT_PORT,
|
|
895
|
-
"data_dir": str(DATA_DIR),
|
|
896
|
-
"telegram_enabled": ENABLE_TELEGRAM,
|
|
897
|
-
"graph_enabled": ENABLE_GRAPH,
|
|
898
|
-
"autoload_models": AUTOLOAD_MODELS,
|
|
899
|
-
"model_idle_unload_seconds": MODEL_IDLE_UNLOAD_SECONDS,
|
|
900
|
-
"model_memory_policy":
|
|
901
|
-
"allow_local_models": ALLOW_LOCAL_MODELS,
|
|
914
|
+
"mode": s.APP_MODE,
|
|
915
|
+
"public": s.IS_PUBLIC_MODE,
|
|
916
|
+
"host": s.DEFAULT_HOST,
|
|
917
|
+
"port": s.DEFAULT_PORT,
|
|
918
|
+
"data_dir": str(s.DATA_DIR),
|
|
919
|
+
"telegram_enabled": s.ENABLE_TELEGRAM,
|
|
920
|
+
"graph_enabled": s.ENABLE_GRAPH,
|
|
921
|
+
"autoload_models": s.AUTOLOAD_MODELS,
|
|
922
|
+
"model_idle_unload_seconds": s.MODEL_IDLE_UNLOAD_SECONDS,
|
|
923
|
+
"model_memory_policy": r.model_memory_policy() if r else None,
|
|
924
|
+
"allow_local_models": s.ALLOW_LOCAL_MODELS,
|
|
902
925
|
"security": {
|
|
903
|
-
"host": DEFAULT_HOST,
|
|
904
|
-
"require_auth": REQUIRE_AUTH,
|
|
905
|
-
"invite_gate_enabled": INVITE_GATE_ENABLED,
|
|
906
|
-
"keyring_available": keyring is not None,
|
|
907
|
-
"plaintext_api_keys_allowed": ALLOW_PLAINTEXT_API_KEYS,
|
|
908
|
-
"cors_allow_network": CORS_ALLOW_NETWORK,
|
|
926
|
+
"host": s.DEFAULT_HOST,
|
|
927
|
+
"require_auth": s.REQUIRE_AUTH,
|
|
928
|
+
"invite_gate_enabled": s.INVITE_GATE_ENABLED,
|
|
929
|
+
"keyring_available": s.keyring is not None,
|
|
930
|
+
"plaintext_api_keys_allowed": s.ALLOW_PLAINTEXT_API_KEYS,
|
|
931
|
+
"cors_allow_network": s.CORS_ALLOW_NETWORK,
|
|
909
932
|
},
|
|
910
|
-
"default_model": PUBLIC_MODEL if IS_PUBLIC_MODE else LOCAL_MODEL,
|
|
933
|
+
"default_model": s.PUBLIC_MODEL if s.IS_PUBLIC_MODE else s.LOCAL_MODEL,
|
|
911
934
|
"local_only_features": {
|
|
912
|
-
"mlx": ALLOW_LOCAL_MODELS and not IS_PUBLIC_MODE,
|
|
913
|
-
"telegram_bridge": ENABLE_TELEGRAM,
|
|
914
|
-
"desktop_chrome_bridge": not IS_PUBLIC_MODE,
|
|
915
|
-
"computer_use_bridge": not IS_PUBLIC_MODE,
|
|
935
|
+
"mlx": s.ALLOW_LOCAL_MODELS and not s.IS_PUBLIC_MODE,
|
|
936
|
+
"telegram_bridge": s.ENABLE_TELEGRAM,
|
|
937
|
+
"desktop_chrome_bridge": not s.IS_PUBLIC_MODE,
|
|
938
|
+
"computer_use_bridge": not s.IS_PUBLIC_MODE,
|
|
916
939
|
},
|
|
917
940
|
"public_features": {
|
|
918
941
|
"web_ui": True,
|
|
919
942
|
"openai_compatible_models": True,
|
|
920
|
-
"persistent_data_dir": str(DATA_DIR),
|
|
943
|
+
"persistent_data_dir": str(s.DATA_DIR),
|
|
921
944
|
},
|
|
922
945
|
}
|
|
923
946
|
|
|
@@ -1099,7 +1122,8 @@ async def _probe_cloud_model(model_ref: str) -> Dict[str, object]:
|
|
|
1099
1122
|
|
|
1100
1123
|
async def verify_cloud_models(force: bool = False, provider_filter: Optional[str] = None) -> Dict[str, Dict]:
|
|
1101
1124
|
now = time.time()
|
|
1102
|
-
|
|
1125
|
+
r = getattr(STATE, "router", None) or router
|
|
1126
|
+
cloud_items = [item for item in (r.detected_cloud_models() if r else []) if item.get("tag") == "cloud"]
|
|
1103
1127
|
if provider_filter:
|
|
1104
1128
|
cloud_items = [item for item in cloud_items if item.get("provider") == provider_filter]
|
|
1105
1129
|
|