ltcai 8.1.0 → 8.3.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 +29 -48
- package/docs/CHANGELOG.md +70 -874
- package/docs/COMMUNITY_AND_PLUGINS.md +43 -0
- package/docs/DEVELOPMENT.md +26 -3
- package/docs/LEGACY_COMPATIBILITY.md +23 -1
- package/docs/ONBOARDING.md +38 -0
- package/docs/TRUST_MODEL.md +26 -26
- package/docs/WHY_LATTICE.md +29 -25
- package/docs/kg-schema.md +7 -5
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/graph/ingest.py +40 -8
- package/lattice_brain/graph/schema.py +6 -0
- package/lattice_brain/runtime/agent_runtime.py +22 -37
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/lattice_brain/workflow.py +26 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/computer_use.py +2 -0
- package/latticeai/api/knowledge_graph.py +33 -0
- package/latticeai/api/local_files.py +2 -0
- package/latticeai/api/memory.py +13 -0
- package/latticeai/api/tools.py +1 -0
- package/latticeai/api/workflow_designer.py +5 -4
- package/latticeai/app_factory.py +30 -28
- package/latticeai/brain/__init__.py +1 -1
- package/latticeai/core/config.py +10 -0
- package/latticeai/core/legacy_compatibility.py +174 -0
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/tool_registry.py +10 -0
- package/latticeai/core/workspace_graph_trace.py +132 -0
- package/latticeai/core/workspace_memory.py +75 -0
- package/latticeai/core/workspace_os.py +135 -1283
- package/latticeai/core/workspace_os_utils.py +132 -0
- package/latticeai/core/workspace_permissions.py +99 -0
- package/latticeai/core/workspace_plugins.py +97 -0
- package/latticeai/core/workspace_runs.py +612 -0
- package/latticeai/core/workspace_skills.py +114 -0
- package/latticeai/core/workspace_snapshots.py +195 -0
- package/latticeai/core/workspace_timeline.py +107 -0
- package/latticeai/runtime/audit_runtime.py +64 -0
- package/latticeai/runtime/config_runtime.py +4 -0
- package/latticeai/runtime/sso_runtime.py +52 -0
- package/latticeai/services/architecture_readiness.py +37 -3
- package/latticeai/services/memory_service.py +215 -7
- package/latticeai/services/model_capability_registry.py +68 -0
- package/latticeai/services/model_engines.py +594 -0
- package/latticeai/services/model_loading.py +482 -0
- package/latticeai/services/model_recommendation.py +5 -0
- package/latticeai/services/model_runtime.py +131 -875
- package/latticeai/services/product_readiness.py +41 -18
- package/llm_router.py +7 -28
- package/mcp_registry.py +7 -24
- package/package.json +1 -1
- package/scripts/pts-claudecode-discord-bridge.mjs +2 -1
- 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 +11 -11
- package/static/app/assets/{Act-BOO66G-c.js → Act-D5mo4tE4.js} +1 -1
- package/static/app/assets/{Brain-C6lEYiD7.js → Brain-BVWyQw8A.js} +1 -1
- package/static/app/assets/{Capture-TATXBRDw.js → Capture-C1R6GT0t.js} +1 -1
- package/static/app/assets/{Library-DK4FIp8a.js → Library-C2wIxpTs.js} +1 -1
- package/static/app/assets/{System-Bgs6Ql7x.js → System-DE5GRyQR.js} +1 -1
- package/static/app/assets/index-CoiuIFFP.js +16 -0
- package/static/app/assets/index-ty1iGgZu.css +2 -0
- package/static/app/assets/{primitives-B70WOra0.js → primitives-BdsUNXa6.js} +1 -1
- package/static/app/assets/{textarea-Czrd9gwM.js → textarea-e7qaj6Hm.js} +1 -1
- package/static/app/index.html +2 -2
- package/static/sw.js +1 -1
- package/tools/__init__.py +2 -1
- package/tools/computer.py +21 -0
- package/docs/CARRYOVER_AUDIT_v3.6.0.md +0 -61
- package/docs/HANDOVER_v3.6.0.md +0 -46
- package/docs/RUNTIME_HOOK_COVERAGE_v3.5.0.md +0 -56
- package/docs/RUNTIME_HOOK_COVERAGE_v3.6.0.md +0 -49
- package/docs/V2_ARCHITECTURE.md +0 -561
- package/docs/V3_2_AUDIT.md +0 -82
- package/docs/V3_BACKEND_ARCHITECTURE.md +0 -138
- package/docs/V3_FRONTEND.md +0 -146
- package/docs/V4_1_FRONTEND_ARCHITECTURE_REVIEW.md +0 -65
- package/docs/V4_1_FRONTEND_MIGRATION_REPORT.md +0 -70
- package/docs/V4_1_VALIDATION_REPORT.md +0 -47
- package/docs/V4_2_BRAIN_CORE_ARCHITECTURE.md +0 -97
- package/docs/V4_2_STORAGE_MIGRATION_REPORT.md +0 -91
- package/docs/V4_2_VALIDATION_REPORT.md +0 -89
- package/docs/V4_3_2_DEADCODE_AUDIT_REPORT.md +0 -174
- package/docs/V4_3_2_DOCUMENTATION_CLEANUP_REPORT.md +0 -81
- package/docs/V4_3_2_GITHUB_VERCEL_CHECK_REPORT.md +0 -75
- package/docs/V4_3_2_GRAPH_UX_REPORT.md +0 -48
- package/docs/V4_3_2_INDEPENDENT_AUDIT_PACKAGE.md +0 -209
- package/docs/V4_3_2_PRODUCT_POLISH_REPORT.md +0 -57
- package/docs/V4_3_2_SELF_AUDIT_REPORT.md +0 -63
- package/docs/V4_3_2_VALIDATION_REPORT.md +0 -97
- package/docs/V4_3_3_VALIDATION_REPORT.md +0 -46
- package/docs/V4_3_PORTABILITY_ARCHITECTURE.md +0 -69
- package/docs/V4_3_PRIVACY_AUDIT.md +0 -60
- package/docs/V4_3_PRODUCT_HARDENING_REPORT.md +0 -53
- package/docs/V4_3_VALIDATION_REPORT.md +0 -58
- package/docs/V4_4_0_EXTRACTION_REPORT.md +0 -239
- package/docs/V4_5_0_GEMMA_RUNTIME_COMPATIBILITY_REPORT.md +0 -49
- package/docs/V4_5_0_GRAPH_UX_REPORT.md +0 -34
- package/docs/V4_5_0_MODEL_RUNTIME_UX_REPORT.md +0 -40
- package/docs/V4_5_0_ONBOARDING_REPORT.md +0 -31
- package/docs/V4_5_0_PRODUCT_EXPERIENCE_RECOVERY_REPORT.md +0 -49
- package/docs/V4_5_0_VALIDATION_REPORT.md +0 -60
- package/docs/V4_5_1_GRAPH_EXPERIENCE_REPORT.md +0 -33
- package/docs/V4_5_1_MODEL_EXPERIENCE_REPORT.md +0 -37
- package/docs/V4_5_1_NAVIGATION_REPORT.md +0 -37
- package/docs/V4_5_1_ONBOARDING_REPORT.md +0 -29
- package/docs/V4_5_1_PRODUCT_REIMAGINING_REPORT.md +0 -61
- package/docs/V4_5_1_RC_ARTIFACTS.md +0 -44
- package/docs/V4_5_1_UX_REPORT.md +0 -45
- package/docs/V4_5_1_VALIDATION_REPORT.md +0 -55
- package/docs/V4_5_1_VISUAL_DESIGN_REPORT.md +0 -30
- package/docs/V4_6_0_LIVING_BRAIN_EXPERIENCE_REPORT.md +0 -72
- package/docs/V4_6_1_RELEASE_REFRESH_REPORT.md +0 -42
- package/docs/V4_7_0_ADMIN_SEPARATION_REPORT.md +0 -42
- package/docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md +0 -49
- package/docs/V4_7_2_INTUITIVE_BRAIN_UX_REPORT.md +0 -62
- package/docs/V4_BRAIN_ARCHITECTURE.md +0 -322
- package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +0 -555
- package/docs/V4_IMPLEMENTATION_PLAN.md +0 -470
- package/static/app/assets/index-Bvv79nre.js +0 -16
- package/static/app/assets/index-Dslqglia.css +0 -2
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Community And Plugins
|
|
2
|
+
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
4
|
+
|
|
5
|
+
LatticeAI 8.3.0 defines the path from a strong local-first framework to a
|
|
6
|
+
product ecosystem. The immediate goal is small and practical: make it clear how
|
|
7
|
+
contributors can extend the Brain without weakening local-first trust,
|
|
8
|
+
workspace scoping, or release quality.
|
|
9
|
+
|
|
10
|
+
## Community Entry Points
|
|
11
|
+
|
|
12
|
+
- Start with the product docs: `README.md`, `docs/WHY_LATTICE.md`, and
|
|
13
|
+
`docs/ONBOARDING.md`.
|
|
14
|
+
- Use `docs/DEVELOPMENT.md` for local setup, validation, and release gates.
|
|
15
|
+
- Use `docs/PLUGIN_SDK.md` for plugin manifests, compatibility, permissions,
|
|
16
|
+
lifecycle state, catalog endpoints, and install flows.
|
|
17
|
+
- Use `plugins/hello-world/plugin.json` as the minimum working plugin shape.
|
|
18
|
+
|
|
19
|
+
## Plugin Direction
|
|
20
|
+
|
|
21
|
+
Plugins should add one bounded capability at a time:
|
|
22
|
+
|
|
23
|
+
- new ingestion sources that still route through `IngestionPipeline`;
|
|
24
|
+
- graph-aware tools that preserve workspace scoping;
|
|
25
|
+
- workflow templates that declare permissions explicitly;
|
|
26
|
+
- editor or automation helpers that keep secrets out of logs and audit payloads;
|
|
27
|
+
- local-first integrations that require explicit opt-in before network access.
|
|
28
|
+
|
|
29
|
+
## Guardrails
|
|
30
|
+
|
|
31
|
+
- No plugin should bypass the ToolRegistry, permission model, or audit hooks.
|
|
32
|
+
- No plugin should write graph data without provenance.
|
|
33
|
+
- No plugin should assume a cloud model, remote registry, or network connection.
|
|
34
|
+
- Compatibility requirements belong in `lattice_version`, and examples should
|
|
35
|
+
use current host-compatible values.
|
|
36
|
+
|
|
37
|
+
## 8.3.0 Ecosystem Tasks
|
|
38
|
+
|
|
39
|
+
- Keep the hello-world plugin valid and boring.
|
|
40
|
+
- Expand examples only when they exercise real extension seams.
|
|
41
|
+
- Add tests before treating a plugin API as stable.
|
|
42
|
+
- Prefer documentation that helps a first contributor build one useful plugin
|
|
43
|
+
over broad ecosystem promises.
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Lattice AI Development
|
|
2
2
|
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
4
|
+
|
|
3
5
|
This document is for contributors working on the local-first Digital Brain
|
|
4
6
|
codebase. Product positioning and quick start stay in `README.md`; release
|
|
5
|
-
history
|
|
7
|
+
history is intentionally limited to 7.0.0-8.3.0 in `docs/CHANGELOG.md` and
|
|
8
|
+
`RELEASE.md`.
|
|
6
9
|
|
|
7
10
|
## Product Contract
|
|
8
11
|
|
|
@@ -77,9 +80,21 @@ Runtime assembly seams live under `latticeai.runtime`:
|
|
|
77
80
|
- `config_runtime.py` derives app config values from `Config`;
|
|
78
81
|
- `security_runtime.py` applies trusted proxy/security-derived settings;
|
|
79
82
|
- `brain_runtime.py` constructs Brain Core and conversation primitives.
|
|
83
|
+
- model/runtime, ToolRegistry/MCP, router, static asset, and lifespan seams
|
|
84
|
+
should continue moving out of monolithic app-factory helpers.
|
|
85
|
+
|
|
86
|
+
Future extraction should continue with AgentRuntime, ToolRegistry, config,
|
|
87
|
+
server decomposition, and Knowledge Graph stabilization in that order when
|
|
88
|
+
architectural debt is present.
|
|
89
|
+
|
|
90
|
+
## Runtime Hook Coverage
|
|
80
91
|
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
Knowledge Graph ingestion paths must continue to pass through the shared
|
|
93
|
+
pre-tool/post-tool lifecycle:
|
|
94
|
+
|
|
95
|
+
- browser `read-url` ingestion dispatches `tool.kg_ingest.*` events;
|
|
96
|
+
- browser `ingest-current-tab` ingestion dispatches the same lifecycle;
|
|
97
|
+
- `IngestionPipeline` remains the common ingestion boundary behind those routes.
|
|
83
98
|
|
|
84
99
|
## Documentation Sync
|
|
85
100
|
|
|
@@ -96,3 +111,11 @@ For user-facing, API, runtime, release, or packaging changes, check:
|
|
|
96
111
|
|
|
97
112
|
Release/publish examples must use exact target-version filenames. Do not
|
|
98
113
|
document wildcard artifact upload commands.
|
|
114
|
+
|
|
115
|
+
For 8.3.0 release work, exact artifacts are:
|
|
116
|
+
|
|
117
|
+
- `dist/ltcai-8.3.0-py3-none-any.whl`
|
|
118
|
+
- `dist/ltcai-8.3.0.tar.gz`
|
|
119
|
+
- `ltcai-8.3.0.tgz`
|
|
120
|
+
- `dist/ltcai-8.3.0.vsix`
|
|
121
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.3.0_aarch64.dmg`
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
# Legacy Compatibility Map
|
|
2
2
|
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
4
|
+
|
|
3
5
|
Lattice AI is moving toward a smaller, modular architecture centered on
|
|
4
6
|
`lattice_brain`, `latticeai.services`, `latticeai.api`, and `latticeai.runtime`.
|
|
5
7
|
Some root-level modules remain packaged for compatibility with older imports,
|
|
6
8
|
CLI entrypoints, or extension workflows. Their presence does not define the
|
|
7
|
-
current architecture.
|
|
9
|
+
current 8.3.0 architecture.
|
|
10
|
+
|
|
11
|
+
8.3.0 also tracks the inner compatibility layers that sit below the root
|
|
12
|
+
modules. The managed inventory lives in `latticeai.core.legacy_compatibility`
|
|
13
|
+
and groups shims by layer:
|
|
14
|
+
|
|
15
|
+
- `root`: historical repo-root imports such as `knowledge_graph.py`.
|
|
16
|
+
- `brain-flat`: pre-graph-package imports such as `lattice_brain.store`.
|
|
17
|
+
- `deprecated-namespace`: older `latticeai.brain.*` package imports.
|
|
18
|
+
- `service-alias`: service paths that now alias Brain runtime modules.
|
|
8
19
|
|
|
9
20
|
## Current Policy
|
|
10
21
|
|
|
@@ -15,6 +26,9 @@ current architecture.
|
|
|
15
26
|
- Add deprecation notes before removal.
|
|
16
27
|
- Avoid breaking package users during a minor release.
|
|
17
28
|
- Do not silently remove rollback, backup, restore, or migration paths.
|
|
29
|
+
- Track every remaining shim through `latticeai.core.legacy_compatibility` so
|
|
30
|
+
release readiness can report owner, replacement, reason, removal phase, and
|
|
31
|
+
missing files.
|
|
18
32
|
|
|
19
33
|
## Root Module Map
|
|
20
34
|
|
|
@@ -33,6 +47,14 @@ current architecture.
|
|
|
33
47
|
| `setup_wizard.py` | setup and model recommendation services | Compatibility for first-run recommendation calls |
|
|
34
48
|
| `server.py` | lazy proxy to `latticeai.server_app` / `latticeai.app_factory` | Preserves historical `server.app` imports without import-time construction |
|
|
35
49
|
|
|
50
|
+
## Inner Shim Layers
|
|
51
|
+
|
|
52
|
+
| Legacy layer | Example module | Current home / direction | Why it remains |
|
|
53
|
+
| --- | --- | --- | --- |
|
|
54
|
+
| `brain-flat` | `lattice_brain.store`, `lattice_brain.ingest`, `lattice_brain.retrieval` | `lattice_brain.graph.*` | Preserves imports from before graph modules were split into a package |
|
|
55
|
+
| `deprecated-namespace` | `latticeai.brain.store`, `latticeai.brain.ingest` | `lattice_brain.graph.*` | Preserves the old application-package Brain namespace |
|
|
56
|
+
| `service-alias` | `latticeai.services.agent_runtime` | `lattice_brain.runtime.agent_runtime` | Preserves service-layer imports while runtime ownership sits in Brain Core |
|
|
57
|
+
|
|
36
58
|
## Packaging Notes
|
|
37
59
|
|
|
38
60
|
`pyproject.toml` and `package.json` still include several root modules because
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Lattice AI Onboarding
|
|
2
|
+
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
4
|
+
|
|
5
|
+
The first-run goal is a five-minute path from "I opened the app" to "my Brain
|
|
6
|
+
has a source, a question, and proof." This page is the product contract behind
|
|
7
|
+
that flow; the UI should make these steps obvious without asking a new user to
|
|
8
|
+
read the docs first.
|
|
9
|
+
|
|
10
|
+
## Five-Minute Flow
|
|
11
|
+
|
|
12
|
+
1. Wake the Brain and confirm the local owner profile.
|
|
13
|
+
2. Let Lattice inspect local model/runtime readiness.
|
|
14
|
+
3. Pick the recommended Brain voice or skip model loading.
|
|
15
|
+
4. Add one source: upload a file, connect a folder, save a note, or capture a
|
|
16
|
+
browser/source event.
|
|
17
|
+
5. Ask one grounded question and inspect the answer proof.
|
|
18
|
+
6. Open the Knowledge Graph only when the user wants source-level evidence.
|
|
19
|
+
7. Back up the Brain once useful memory exists.
|
|
20
|
+
|
|
21
|
+
## Product Promises
|
|
22
|
+
|
|
23
|
+
- The user starts in the Brain, not in an admin dashboard.
|
|
24
|
+
- Empty states suggest one concrete next action without claiming proof that does
|
|
25
|
+
not exist yet.
|
|
26
|
+
- Upload, note, browser, and message ingestion all converge through the unified
|
|
27
|
+
ingestion pipeline when it is available.
|
|
28
|
+
- Workspace-scoped content must not leak or overwrite another workspace's graph
|
|
29
|
+
metadata.
|
|
30
|
+
- Advanced runtime, workflow, plugin, and admin surfaces are available, but they
|
|
31
|
+
do not block the first conversation.
|
|
32
|
+
|
|
33
|
+
## Release Gate
|
|
34
|
+
|
|
35
|
+
8.3.0 treats onboarding as a release gate, not marketing copy. The current
|
|
36
|
+
machine-checkable product readiness report requires this five-minute contract,
|
|
37
|
+
the Brain Home surface, setup helpers, graph ingestion tests, and exact release
|
|
38
|
+
artifact documentation before the release can be called complete.
|
package/docs/TRUST_MODEL.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Lattice AI Trust Model
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
4
|
+
|
|
5
|
+
Lattice AI is local-first, explicit about external communication, and honest
|
|
6
|
+
when a capability is unavailable.
|
|
5
7
|
|
|
6
8
|
## Local By Default
|
|
7
9
|
|
|
@@ -9,58 +11,56 @@ By default, Lattice AI binds the API to `127.0.0.1`, stores Brain data under the
|
|
|
9
11
|
local data directory, and does not send prompts, documents, graph content, or
|
|
10
12
|
archives to Lattice-owned servers.
|
|
11
13
|
|
|
12
|
-
Local data
|
|
14
|
+
Local data can include:
|
|
13
15
|
|
|
14
|
-
-
|
|
15
|
-
- conversations and
|
|
16
|
-
- Knowledge Graph nodes, edges, provenance, and
|
|
17
|
-
- uploaded document blobs;
|
|
16
|
+
- profile and session metadata;
|
|
17
|
+
- conversations, memories, decisions, and workflow history;
|
|
18
|
+
- Knowledge Graph nodes, edges, provenance, and indexes;
|
|
19
|
+
- uploaded document blobs and extracted text;
|
|
18
20
|
- audit and admin operation logs;
|
|
19
21
|
- backups and encrypted `.latticebrain` archives.
|
|
20
22
|
|
|
21
23
|
## Explicit External Paths
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
action or configuration:
|
|
25
|
+
External communication requires configuration plus a user/admin action:
|
|
25
26
|
|
|
26
|
-
- model
|
|
27
|
-
-
|
|
27
|
+
- cloud model calls after keys are configured and a cloud model is selected;
|
|
28
|
+
- model downloads from registries after install consent;
|
|
28
29
|
- Telegram bridge after the integration is enabled;
|
|
29
|
-
- Brain Network peer actions after pairing
|
|
30
|
+
- Brain Network peer actions after pairing;
|
|
30
31
|
- Docker/Postgres setup after opt-in scale configuration;
|
|
31
|
-
- update checks only when
|
|
32
|
-
- remote
|
|
32
|
+
- update checks only when enabled;
|
|
33
|
+
- marketplace or remote registry refreshes only when invoked.
|
|
33
34
|
|
|
34
35
|
Token presence alone must not start external communication.
|
|
35
36
|
|
|
36
37
|
## Consent And Honesty Gates
|
|
37
38
|
|
|
38
|
-
Lattice AI should fail closed or
|
|
39
|
+
Lattice AI should fail closed or show an unavailable state for:
|
|
39
40
|
|
|
40
41
|
- no model loaded;
|
|
41
|
-
- local model not installed;
|
|
42
|
-
- installed model not loaded;
|
|
42
|
+
- local model not installed or not loaded;
|
|
43
43
|
- missing cloud key;
|
|
44
44
|
- deterministic/model-free preview;
|
|
45
45
|
- dry-run versus real execution;
|
|
46
46
|
- no graph/context evidence available;
|
|
47
47
|
- unavailable external integration;
|
|
48
48
|
- wrong archive passphrase;
|
|
49
|
-
- archive
|
|
49
|
+
- archive tampering, unsupported archive versions, or path traversal.
|
|
50
50
|
|
|
51
|
-
##
|
|
51
|
+
## Product Boundary
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
Normal Brain use is conversation, memory, topics, relationships, model state,
|
|
54
|
+
source capture, and Knowledge Graph exploration. Admin Console is for users,
|
|
55
55
|
roles, audit logs, security events, retention, and operations. Admin visibility
|
|
56
56
|
does not mean secrets should appear in clear text.
|
|
57
57
|
|
|
58
|
-
## Known
|
|
58
|
+
## Known Limits
|
|
59
59
|
|
|
60
|
-
- Local files are only as protected as the user's machine, account, backups,
|
|
61
|
-
disk encryption.
|
|
62
|
-
- Cloud model prompts follow the selected provider's policy
|
|
60
|
+
- Local files are only as protected as the user's machine, OS account, backups,
|
|
61
|
+
and disk encryption.
|
|
62
|
+
- Cloud model prompts follow the selected provider's policy once the user
|
|
63
|
+
explicitly chooses that provider.
|
|
63
64
|
- A local admin can inspect local files and process memory outside Lattice AI.
|
|
64
65
|
- Marketplace and model registries are third-party services when explicitly
|
|
65
66
|
contacted.
|
|
66
|
-
|
package/docs/WHY_LATTICE.md
CHANGED
|
@@ -1,51 +1,55 @@
|
|
|
1
1
|
# Why Lattice AI Exists
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
4
|
+
|
|
5
|
+
**Lattice AI is a local-first Digital Brain that keeps your knowledge durable
|
|
6
|
+
across any AI model.**
|
|
4
7
|
|
|
5
8
|
**모델은 바꿔도, 내 지식은 남는 로컬 AI 브레인.**
|
|
6
9
|
|
|
7
|
-
AI models change quickly. A model you use today may be replaced
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
asset is not the model. The durable asset is your Brain.
|
|
10
|
+
AI models change quickly. A model you use today may be replaced tomorrow, and a
|
|
11
|
+
cloud chat history can become scattered across tools. Lattice AI exists so the
|
|
12
|
+
durable asset is not the model. The durable asset is your Brain.
|
|
11
13
|
|
|
12
14
|
## The Problem
|
|
13
15
|
|
|
14
|
-
Most AI products
|
|
15
|
-
material. That
|
|
16
|
+
Most AI products start with a model and treat your context as temporary prompt
|
|
17
|
+
material. That breaks down for real work:
|
|
16
18
|
|
|
17
19
|
- project decisions disappear into old chats;
|
|
18
|
-
- documents and notes
|
|
20
|
+
- documents and notes stay disconnected from conversations;
|
|
19
21
|
- switching models often means losing useful context;
|
|
20
|
-
- graph
|
|
21
|
-
- cloud-only products make
|
|
22
|
+
- graph tools expose implementation detail before user value;
|
|
23
|
+
- cloud-only products make your knowledge hard to inspect, back up, or move.
|
|
22
24
|
|
|
23
25
|
## The Lattice Answer
|
|
24
26
|
|
|
25
|
-
Lattice AI
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
Lattice AI keeps conversations, documents, memories, decisions, relationships,
|
|
28
|
+
and source provenance in a private local Brain. Models can be local, cloud,
|
|
29
|
+
current, or future. The Brain remains.
|
|
30
|
+
|
|
31
|
+
The graph matters, but it is not the product identity. The product identity is a
|
|
32
|
+
local-first Digital Brain: a place where the user can talk, add sources, watch
|
|
33
|
+
memory grow, and inspect the Knowledge Graph when they need proof.
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Advanced admin logs, roles, hooks, workflows, Telegram, Brain Network, Docker,
|
|
34
|
-
Postgres, and plugin details stay outside the normal user flow.
|
|
35
|
+
In 8.3.0 the first screen is intentionally not a dashboard. The living Brain,
|
|
36
|
+
conversation composer, evidence-backed Brain Brief, and five-minute onboarding
|
|
37
|
+
path appear together so the user immediately knows what matters, what to add,
|
|
38
|
+
and why the answer is grounded in local memory.
|
|
35
39
|
|
|
36
40
|
## Practical Reasons To Use It
|
|
37
41
|
|
|
38
|
-
- Ask what the team decided
|
|
39
|
-
-
|
|
40
|
-
- Prepare
|
|
41
|
-
- Preserve context when moving
|
|
42
|
-
- Export or
|
|
42
|
+
- Ask what the team decided and see the source.
|
|
43
|
+
- Add documents and build a searchable private memory.
|
|
44
|
+
- Prepare from old notes, project decisions, and files.
|
|
45
|
+
- Preserve context when moving between models.
|
|
46
|
+
- Export or restore the Brain as an encrypted `.latticebrain` archive.
|
|
43
47
|
- Use Korean or English without changing the underlying Brain.
|
|
44
48
|
- Avoid fake answers when no model or evidence is available.
|
|
45
49
|
|
|
46
50
|
## What Lattice AI Is Not
|
|
47
51
|
|
|
48
|
-
- Not
|
|
52
|
+
- Not hosted SaaS by default.
|
|
49
53
|
- Not just a model launcher.
|
|
50
54
|
- Not just a graph viewer.
|
|
51
55
|
- Not a generic dashboard.
|
package/docs/kg-schema.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# Knowledge Graph
|
|
1
|
+
# Knowledge Graph Schema
|
|
2
|
+
|
|
3
|
+
Current release: **8.3.0 - Orchestrated Brain Readiness**.
|
|
2
4
|
|
|
3
5
|
명세 출처: `lattice_ai_full_spec.pptx` 슬라이드 20·21·22
|
|
4
6
|
구현: `kg_schema.py`
|
|
@@ -80,15 +82,15 @@ Edge {
|
|
|
80
82
|
|
|
81
83
|
**엔드포인트 룰은 권고 사항이다 (스키마 문서 기준).** 코드에는 엔드포인트 페어
|
|
82
84
|
검증기가 존재하지 않는다 — `validate_endpoints` 는 구현된 적이 없으며, 쓰기
|
|
83
|
-
경로는 타입 페어를 거부하지 않는다.
|
|
85
|
+
경로는 타입 페어를 거부하지 않는다. 현재 쓰기 정규화는 *타입 어휘* 를
|
|
84
86
|
강제한다: `_upsert_edge` 가 모든 엣지 타입을 canonical `EdgeType` 값으로
|
|
85
87
|
정규화하므로 자유 문자열 타입은 더 이상 생성되지 않는다.
|
|
86
88
|
|
|
87
89
|
---
|
|
88
90
|
|
|
89
|
-
##
|
|
91
|
+
## Current Knowledge Graph First 엔티티/관계
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
8.3.0 은 "모든 데이터 소스가 Knowledge Graph 로 수렴한다"는 원칙을 1급 스키마로
|
|
92
94
|
승격한다. 아래 타입은 **추가형(additive)**이다 — 기존 enum/legacy 매핑을 깨지 않고
|
|
93
95
|
`from_legacy` 가 무손실로 정규화하며, 알 수 없는 타입은 여전히 `CONCEPT`/`MENTIONS` 로
|
|
94
96
|
폴백한다. 스키마는 **확장 가능**하게 유지한다: 새 도메인 엔티티는 enum 멤버 1개 +
|
|
@@ -136,7 +138,7 @@ provenance(source_type, source_uri, content_hash, captured_at, modified_at,
|
|
|
136
138
|
- provenance 는 노드 `metadata.provenance` 에 임베드되며, 동시에 감사 가능한
|
|
137
139
|
`ingestion_provenance` 테이블에 기록된다 (`KnowledgeGraphStore.get_provenance(node_id)`).
|
|
138
140
|
|
|
139
|
-
구현: `
|
|
141
|
+
구현: `lattice_brain/ingestion.py` (`IngestionPipeline`) 가 단일 진입점이며,
|
|
140
142
|
파일/로컬폴더/URL/브라우저 탭/텍스트를 모두 이 형태로 정규화한다.
|
|
141
143
|
|
|
142
144
|
---
|
|
@@ -490,8 +490,6 @@ class KnowledgeGraphIngestMixin:
|
|
|
490
490
|
is derived from (source_type, source_uri | content_hash) so re-ingesting
|
|
491
491
|
the same origin reuses the same SOURCE node (idempotent).
|
|
492
492
|
"""
|
|
493
|
-
key = source_uri or content_hash or content_node_id
|
|
494
|
-
source_id = f"source:{_sha256_text(f'{source_type}|{key}')[:24]}"
|
|
495
493
|
meta = {
|
|
496
494
|
"source_type": source_type,
|
|
497
495
|
"source_uri": source_uri,
|
|
@@ -499,6 +497,9 @@ class KnowledgeGraphIngestMixin:
|
|
|
499
497
|
"captured_at": captured_at or _now(),
|
|
500
498
|
**(extra or {}),
|
|
501
499
|
}
|
|
500
|
+
key = source_uri or content_hash or content_node_id
|
|
501
|
+
source_scope = meta.get("workspace_id") or "legacy-global"
|
|
502
|
+
source_id = f"source:{_sha256_text(f'{source_scope}|{source_type}|{key}')[:24]}"
|
|
502
503
|
label = title or source_uri or source_type
|
|
503
504
|
self._upsert_node(
|
|
504
505
|
conn,
|
|
@@ -551,7 +552,8 @@ class KnowledgeGraphIngestMixin:
|
|
|
551
552
|
)
|
|
552
553
|
captured_at = captured_at or _now()
|
|
553
554
|
content_hash = _sha256_text(f"{source_type}|{source_uri or ''}|{text}")
|
|
554
|
-
|
|
555
|
+
identity_hash = _sha256_text(f"{workspace_id or 'legacy-global'}|{content_hash}")
|
|
556
|
+
content_id = f"webdoc:{identity_hash[:24]}"
|
|
555
557
|
full_text = f"{title}\n{text}"
|
|
556
558
|
node_meta = {
|
|
557
559
|
"source_type": source_type,
|
|
@@ -581,6 +583,8 @@ class KnowledgeGraphIngestMixin:
|
|
|
581
583
|
summary=(text or title)[:500],
|
|
582
584
|
metadata=node_meta,
|
|
583
585
|
raw=node_meta,
|
|
586
|
+
owner=owner,
|
|
587
|
+
workspace_id=workspace_id,
|
|
584
588
|
)
|
|
585
589
|
# ── SOURCE 노드 + indexed_from 엣지 (출처 추적) ──────────────────
|
|
586
590
|
source_node_id = self._attach_source_node(
|
|
@@ -597,13 +601,27 @@ class KnowledgeGraphIngestMixin:
|
|
|
597
601
|
if owner:
|
|
598
602
|
person_id = f"person:{_slug(owner)}"
|
|
599
603
|
self._upsert_node(
|
|
600
|
-
conn,
|
|
604
|
+
conn,
|
|
605
|
+
person_id,
|
|
606
|
+
"Person",
|
|
607
|
+
owner,
|
|
608
|
+
metadata={"email": owner, "workspace_id": workspace_id},
|
|
609
|
+
owner=owner,
|
|
610
|
+
workspace_id=workspace_id,
|
|
601
611
|
)
|
|
602
612
|
self._upsert_edge(conn, person_id, content_id, "업로드함", weight=1.0)
|
|
603
613
|
# ── 대화 연결 ───────────────────────────────────────────────────
|
|
604
614
|
if conversation_id:
|
|
605
615
|
conv_id = f"conversation:{_slug(conversation_id)}"
|
|
606
|
-
self._upsert_node(
|
|
616
|
+
self._upsert_node(
|
|
617
|
+
conn,
|
|
618
|
+
conv_id,
|
|
619
|
+
"Chat",
|
|
620
|
+
conversation_id,
|
|
621
|
+
metadata={"conversation_id": conversation_id, "workspace_id": workspace_id},
|
|
622
|
+
owner=owner,
|
|
623
|
+
workspace_id=workspace_id,
|
|
624
|
+
)
|
|
607
625
|
self._upsert_edge(conn, conv_id, content_id, "언급함", weight=0.8)
|
|
608
626
|
# ── RAG 청크 ────────────────────────────────────────────────────
|
|
609
627
|
for index, chunk in enumerate(_chunks(text)):
|
|
@@ -615,7 +633,9 @@ class KnowledgeGraphIngestMixin:
|
|
|
615
633
|
"Chunk",
|
|
616
634
|
f"{title} chunk {index + 1}",
|
|
617
635
|
summary=chunk[:500],
|
|
618
|
-
metadata={"index": index, "source_node": content_id},
|
|
636
|
+
metadata={"index": index, "source_node": content_id, "workspace_id": workspace_id},
|
|
637
|
+
owner=owner,
|
|
638
|
+
workspace_id=workspace_id,
|
|
619
639
|
)
|
|
620
640
|
self._upsert_chunk(
|
|
621
641
|
conn,
|
|
@@ -636,7 +656,13 @@ class KnowledgeGraphIngestMixin:
|
|
|
636
656
|
cid,
|
|
637
657
|
node_t,
|
|
638
658
|
concept,
|
|
639
|
-
metadata={
|
|
659
|
+
metadata={
|
|
660
|
+
"auto_extracted": True,
|
|
661
|
+
"source_type": source_type,
|
|
662
|
+
"workspace_id": workspace_id,
|
|
663
|
+
},
|
|
664
|
+
owner=owner,
|
|
665
|
+
workspace_id=workspace_id,
|
|
640
666
|
)
|
|
641
667
|
self._upsert_edge(conn, content_id, cid, "포함함", weight=0.8)
|
|
642
668
|
for triple in triples:
|
|
@@ -662,8 +688,14 @@ class KnowledgeGraphIngestMixin:
|
|
|
662
688
|
sem_type,
|
|
663
689
|
sem_title,
|
|
664
690
|
summary=item["summary"],
|
|
665
|
-
metadata={
|
|
691
|
+
metadata={
|
|
692
|
+
"auto_extracted": True,
|
|
693
|
+
"source_node": content_id,
|
|
694
|
+
"workspace_id": workspace_id,
|
|
695
|
+
},
|
|
666
696
|
raw=item,
|
|
697
|
+
owner=owner,
|
|
698
|
+
workspace_id=workspace_id,
|
|
667
699
|
)
|
|
668
700
|
self._upsert_edge(conn, content_id, sem_id, "포함함", weight=0.9)
|
|
669
701
|
|
|
@@ -56,6 +56,12 @@ KG_SCHEMA_V2_VERSION = 2
|
|
|
56
56
|
EMBED_DIM = int(os.getenv("LATTICEAI_EMBED_DIM", "1024"))
|
|
57
57
|
|
|
58
58
|
|
|
59
|
+
def set_embed_dim(dim: int) -> None:
|
|
60
|
+
"""Optional way for upper layers to override without direct module import at top level in lattice_brain."""
|
|
61
|
+
global EMBED_DIM
|
|
62
|
+
EMBED_DIM = int(dim) # lattice_brain isolation: no direct latticeai import; callers can pre-set env if using central Config
|
|
63
|
+
|
|
64
|
+
|
|
59
65
|
# ── Node / Edge taxonomy (PPT 슬라이드 20·21) ──────────────────────────────
|
|
60
66
|
class NodeType(str, Enum):
|
|
61
67
|
"""워크스페이스의 모든 ‘명사’.
|
|
@@ -266,7 +266,7 @@ class AgentRuntime:
|
|
|
266
266
|
unknown_roles = [role for role in requested_roles if role not in AGENT_ROLES]
|
|
267
267
|
health = self.health()
|
|
268
268
|
goal_ready = bool(str(goal or "").strip())
|
|
269
|
-
retry_budget =
|
|
269
|
+
retry_budget = self._clamp_retries(max_retries)
|
|
270
270
|
blocking_reasons: List[str] = []
|
|
271
271
|
if not goal_ready:
|
|
272
272
|
blocking_reasons.append("goal is required")
|
|
@@ -324,6 +324,7 @@ class AgentRuntime:
|
|
|
324
324
|
def events(self, run_id: str, *, scope: Optional[str] = None) -> Dict[str, Any]:
|
|
325
325
|
run = self._store.get_agent_run(run_id, workspace_id=scope)
|
|
326
326
|
status = str(run.get("status") or "")
|
|
327
|
+
contract = extract_contract(run)
|
|
327
328
|
return {
|
|
328
329
|
"run_id": run_id,
|
|
329
330
|
"status": status,
|
|
@@ -331,7 +332,7 @@ class AgentRuntime:
|
|
|
331
332
|
"current_role": run.get("current_role"),
|
|
332
333
|
"timeline": run.get("timeline") or [],
|
|
333
334
|
"handoffs": run.get("handoffs") or [],
|
|
334
|
-
"contract": contract_view(
|
|
335
|
+
"contract": contract_view(contract) if contract is not None else None,
|
|
335
336
|
}
|
|
336
337
|
|
|
337
338
|
# ── execution ─────────────────────────────────────────────────────────
|
|
@@ -360,6 +361,9 @@ class AgentRuntime:
|
|
|
360
361
|
raise PermissionError(pre_dispatch.get("block_reason") or "Agent run blocked by a pre_run hook.")
|
|
361
362
|
return pre_dispatch
|
|
362
363
|
|
|
364
|
+
def _clamp_retries(self, max_retries: int) -> int:
|
|
365
|
+
return max(0, min(int(max_retries or 0), self._max_retries_cap))
|
|
366
|
+
|
|
363
367
|
@staticmethod
|
|
364
368
|
def _result_patch(result: Any, goal: str) -> Dict[str, Any]:
|
|
365
369
|
return {
|
|
@@ -488,7 +492,7 @@ class AgentRuntime:
|
|
|
488
492
|
workspace_id=scope,
|
|
489
493
|
inputs=inputs or {},
|
|
490
494
|
roles=roles or None,
|
|
491
|
-
max_retries=
|
|
495
|
+
max_retries=self._clamp_retries(max_retries),
|
|
492
496
|
)
|
|
493
497
|
except Exception as exc:
|
|
494
498
|
failed = self._store.update_agent_run(
|
|
@@ -571,25 +575,13 @@ class AgentRuntime:
|
|
|
571
575
|
if not str(goal or "").strip():
|
|
572
576
|
raise ValueError("goal is required")
|
|
573
577
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
"pre_run", "agent.run",
|
|
582
|
-
payload={"goal": goal, "roles": roles or None, "max_retries": max_retries},
|
|
583
|
-
user_email=user_email, workspace_id=scope,
|
|
584
|
-
)
|
|
585
|
-
if pre_dispatch.get("blocked"):
|
|
586
|
-
self._append_audit_event(
|
|
587
|
-
"multi_agent_run_blocked",
|
|
588
|
-
user_email=user_email,
|
|
589
|
-
reason=pre_dispatch.get("block_reason"),
|
|
590
|
-
)
|
|
591
|
-
raise PermissionError(pre_dispatch.get("block_reason") or "Agent run blocked by a pre_run hook.")
|
|
592
|
-
|
|
578
|
+
pre_dispatch = self._fire_pre_run(
|
|
579
|
+
goal=goal,
|
|
580
|
+
roles=roles,
|
|
581
|
+
max_retries=max_retries,
|
|
582
|
+
user_email=user_email,
|
|
583
|
+
scope=scope,
|
|
584
|
+
)
|
|
593
585
|
orchestrator = self._live_orchestrator(user_email, scope)
|
|
594
586
|
result = orchestrator.run(
|
|
595
587
|
goal,
|
|
@@ -597,7 +589,7 @@ class AgentRuntime:
|
|
|
597
589
|
workspace_id=scope,
|
|
598
590
|
inputs=inputs or {},
|
|
599
591
|
roles=roles or None,
|
|
600
|
-
max_retries=
|
|
592
|
+
max_retries=self._clamp_retries(max_retries),
|
|
601
593
|
)
|
|
602
594
|
run = self._store.record_agent_run(
|
|
603
595
|
agent_id=result.agent_id,
|
|
@@ -626,20 +618,13 @@ class AgentRuntime:
|
|
|
626
618
|
retries=result.retries,
|
|
627
619
|
)
|
|
628
620
|
|
|
629
|
-
|
|
630
|
-
post_dispatch
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
"run_id": run_id,
|
|
637
|
-
"agent_id": result.agent_id,
|
|
638
|
-
"status": result.status,
|
|
639
|
-
"retries": result.retries,
|
|
640
|
-
},
|
|
641
|
-
user_email=user_email, workspace_id=scope,
|
|
642
|
-
)
|
|
621
|
+
run_id = run.get("id") or run.get("run_id") if isinstance(run, dict) else None
|
|
622
|
+
post_dispatch = self._post_run_hooks(
|
|
623
|
+
run_id=run_id,
|
|
624
|
+
result=result,
|
|
625
|
+
user_email=user_email,
|
|
626
|
+
scope=scope,
|
|
627
|
+
)
|
|
643
628
|
|
|
644
629
|
result_payload = result.as_dict()
|
|
645
630
|
result_payload["contract"] = multi_agent_contract(result=result, goal=goal, run_id=run.get("id") if isinstance(run, dict) else None)
|
|
@@ -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.3.0"
|
|
25
25
|
|
|
26
26
|
AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
|
|
27
27
|
CORE_PIPELINE = ("planner", "executor", "reviewer")
|