ltcai 8.2.0 → 8.4.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 +27 -19
- package/docs/CHANGELOG.md +59 -0
- package/docs/COMMUNITY_AND_PLUGINS.md +43 -0
- package/docs/DEVELOPMENT.md +8 -8
- package/docs/LEGACY_COMPATIBILITY.md +22 -2
- package/docs/ONBOARDING.md +38 -0
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +5 -4
- package/docs/kg-schema.md +3 -3
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/graph/ingest.py +40 -8
- 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/chat.py +230 -51
- package/latticeai/api/knowledge_graph.py +33 -0
- package/latticeai/api/local_files.py +2 -0
- package/latticeai/api/tools.py +1 -0
- package/latticeai/api/workflow_designer.py +5 -4
- package/latticeai/core/legacy_compatibility.py +174 -0
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/latticeai/services/architecture_readiness.py +37 -3
- package/latticeai/services/model_catalog.py +6 -0
- package/latticeai/services/model_engines.py +12 -21
- package/latticeai/services/model_runtime.py +17 -23
- package/latticeai/services/product_readiness.py +45 -14
- 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 +10 -10
- package/static/app/assets/{Act-D9jIknFd.js → Act-D5mo4tE4.js} +1 -1
- package/static/app/assets/{Brain-CFOtWbPN.js → Brain-BVWyQw8A.js} +1 -1
- package/static/app/assets/{Capture-Q4WYzwr5.js → Capture-C1R6GT0t.js} +1 -1
- package/static/app/assets/{Library-C5Q2yWee.js → Library-C2wIxpTs.js} +1 -1
- package/static/app/assets/{System-BLbjdr1_.js → System-DE5GRyQR.js} +1 -1
- package/static/app/assets/{index-BqammyNu.js → index-CoiuIFFP.js} +3 -3
- package/static/app/assets/{primitives-Br8uSfZ4.js → primitives-BdsUNXa6.js} +1 -1
- package/static/app/assets/{textarea-BnhNs1_X.js → textarea-e7qaj6Hm.js} +1 -1
- package/static/app/index.html +1 -1
- package/static/sw.js +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI
|
|
2
2
|
|
|
3
|
-
**Lattice AI 8.0 is the local-first Digital Brain platform with
|
|
3
|
+
**Lattice AI 8.4.0 is the local-first Digital Brain platform with action-aware Brain Chat that creates files through the governed workspace file tool instead of only returning code.**
|
|
4
4
|
|
|
5
5
|
**Lattice AI는 모델이 바뀌어도 내 지식과 맥락을 보존하는 로컬 우선 AI 브레인입니다.**
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ downloads, update checks, and other external communication happen only after
|
|
|
11
11
|
explicit consent.
|
|
12
12
|
|
|
13
13
|
It is not a ChatGPT clone, a model launcher, a graph database, or a note app.
|
|
14
|
-
It is the finished private AI memory layer wrapped in a Living Brain experience — now with
|
|
14
|
+
It is the finished private AI memory layer wrapped in a Living Brain experience — now with an 8.4.0 action-readiness contract behind chat-to-tool file creation, onboarding, orchestration, graph ingestion, and the plugin/community path.
|
|
15
15
|
|
|
16
16
|
[](https://pypi.org/project/ltcai/)
|
|
17
17
|
[](https://www.npmjs.com/package/ltcai)
|
|
@@ -64,9 +64,10 @@ You need Lattice AI when:
|
|
|
64
64
|
|
|
65
65
|
## Living Brain Flow
|
|
66
66
|
|
|
67
|
-
The screenshots below are
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
The screenshots below are the latest checked-in visual evidence captures from
|
|
68
|
+
the 8.2 Brain Home release. The 8.3 line keeps that first-run flow focused on
|
|
69
|
+
the Brain while adding clearer onboarding, stronger workflow/runtime
|
|
70
|
+
boundaries, and better ingestion proof behind the scenes.
|
|
70
71
|
|
|
71
72
|
### 1. Wake Brain
|
|
72
73
|
|
|
@@ -203,27 +204,32 @@ See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for developer workflow details.
|
|
|
203
204
|
|
|
204
205
|
## Current Release
|
|
205
206
|
|
|
206
|
-
The current release is **8.
|
|
207
|
+
The current release is **8.4.0 — Action-Aware Brain Chat**:
|
|
207
208
|
|
|
208
|
-
- Brain
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
|
|
213
|
-
|
|
209
|
+
- Brain Chat now routes explicit file create/write/save/edit requests through
|
|
210
|
+
the governed workspace file tool instead of treating them as ordinary prose
|
|
211
|
+
generation.
|
|
212
|
+
- Requests such as `hello.md 파일 만들어줘` are executed through
|
|
213
|
+
`write_file`/`edit_file` style tool paths, and created artifacts are returned
|
|
214
|
+
in the chat response.
|
|
215
|
+
- Normal Q&A stays on the low-friction `/chat` generation path; only explicit
|
|
216
|
+
side-effect requests move into the tool-running agent loop.
|
|
217
|
+
- The release keeps the 8.3.0 managed legacy inventory, AgentRuntime/workflow
|
|
218
|
+
boundaries, unified graph ingestion, and workspace-safe duplicate content
|
|
219
|
+
protections active.
|
|
214
220
|
|
|
215
|
-
Expected artifacts for 8.
|
|
221
|
+
Expected artifacts for 8.4.0 release must use exact filenames:
|
|
216
222
|
|
|
217
|
-
- `dist/ltcai-8.
|
|
218
|
-
- `dist/ltcai-8.
|
|
219
|
-
- `ltcai-8.
|
|
220
|
-
- `dist/ltcai-8.
|
|
221
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.
|
|
223
|
+
- `dist/ltcai-8.4.0-py3-none-any.whl`
|
|
224
|
+
- `dist/ltcai-8.4.0.tar.gz`
|
|
225
|
+
- `ltcai-8.4.0.tgz`
|
|
226
|
+
- `dist/ltcai-8.4.0.vsix`
|
|
227
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.4.0_aarch64.dmg`
|
|
222
228
|
|
|
223
229
|
Do not use wildcard artifact uploads. Package registry publishing remains owner-run.
|
|
224
230
|
|
|
225
231
|
See [docs/ROADMAP_RECOMMENDATIONS.md](docs/ROADMAP_RECOMMENDATIONS.md) for the
|
|
226
|
-
strategic roadmap slices applied through 8.
|
|
232
|
+
strategic roadmap slices applied through 8.4.0 and the follow-up tracks.
|
|
227
233
|
|
|
228
234
|
## Known Limitations
|
|
229
235
|
|
|
@@ -240,6 +246,8 @@ strategic roadmap slices applied through 8.2.0 and the follow-up tracks.
|
|
|
240
246
|
|
|
241
247
|
| Version | Theme |
|
|
242
248
|
| --- | --- |
|
|
249
|
+
| 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 |
|
|
250
|
+
| 8.3.0 | Orchestrated Brain Readiness: managed legacy shim inventory, stronger AgentRuntime/workflow boundaries, unified graph ingestion, workspace-safe duplicate content, first-run onboarding, and explicit community/plugin growth path |
|
|
243
251
|
| 8.2.0 | Brain Brief: evidence-backed home briefing, honest empty-state guidance, recall/graph/model-proof next actions, and continued model/workspace runtime extraction |
|
|
244
252
|
| 8.1.0 | Intuitive Brain Home: living Brain, recent memory, connected topic, next action, and composer are visible in one product-first screen with refreshed 8.1.0 evidence and artifacts |
|
|
245
253
|
| 8.0.0 | Runtime Architecture Contract: AgentRuntime, ToolRegistry, central Config, server decomposition, and KG hardening are captured as machine-checkable release boundaries with exact 8.0.0 artifacts |
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,65 @@ existed at that release.
|
|
|
8
8
|
|
|
9
9
|
No unreleased changes.
|
|
10
10
|
|
|
11
|
+
## [8.4.0] - 2026-07-01
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Added a chat-to-agent file action gate so explicit file create/write/save/edit
|
|
15
|
+
requests from Brain Chat execute through the governed workspace file tool.
|
|
16
|
+
- Added regression coverage that verifies `/chat` routes file creation intent to
|
|
17
|
+
the workspace file tool and returns created artifact metadata.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- Kept ordinary Q&A on `/chat` while routing only explicit side-effect file
|
|
21
|
+
requests into the planner/executor/reviewer tool loop.
|
|
22
|
+
- Synchronized package/runtime/static/Tauri metadata and current-release docs to
|
|
23
|
+
8.4.0.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Allowed literal `/chat` file writes with user-provided content to execute
|
|
27
|
+
before model loading, while still using a loaded model when content must be
|
|
28
|
+
synthesized.
|
|
29
|
+
- Narrowed file target and content parsing to avoid treating surrounding prose
|
|
30
|
+
as the workspace path or literal file body.
|
|
31
|
+
- Restored model loading dependency exports after the runtime/loading split so
|
|
32
|
+
`/models/load` can prepare local MLX models again.
|
|
33
|
+
- Added the common Gemma 4 26B shorthand alias to the canonical
|
|
34
|
+
`mlx-community/gemma-4-26b-a4b-it-4bit` model id.
|
|
35
|
+
- Updated the local server launcher to run `python -m uvicorn` from the active
|
|
36
|
+
virtual environment, avoiding stale console-script interpreter bindings.
|
|
37
|
+
|
|
38
|
+
## [8.3.0] - 2026-07-01
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- Added a managed legacy compatibility report for remaining root shims,
|
|
42
|
+
including owners, replacements, reasons, removal phases, and readiness
|
|
43
|
+
metrics.
|
|
44
|
+
- Added AgentRuntime/workflow maturity evidence through lifecycle helper reuse,
|
|
45
|
+
legacy event compatibility, WorkflowEngine boundary/config inspection, and
|
|
46
|
+
centralized legacy workflow step projection.
|
|
47
|
+
- Added graph ingestion coverage for upload-to-pipeline behavior and
|
|
48
|
+
workspace-safe duplicate content.
|
|
49
|
+
- Added 8.3.0 onboarding and community/plugin growth documentation.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- Routed `/knowledge-graph/ingest` through the unified `IngestionPipeline` when
|
|
53
|
+
available, preserving provenance and hook lifecycle behavior for MCP notes and
|
|
54
|
+
messages.
|
|
55
|
+
- Isolated text/web/note graph node identity by workspace while preserving the
|
|
56
|
+
content hash used for duplicate detection.
|
|
57
|
+
- Converted `mcp_registry.py` and `llm_router.py` into physical module aliases
|
|
58
|
+
for their current implementations.
|
|
59
|
+
- Improved upload client error handling so failed uploads cannot look
|
|
60
|
+
successful.
|
|
61
|
+
- Synchronized package/runtime/static/Tauri metadata and current-release docs to
|
|
62
|
+
8.3.0.
|
|
63
|
+
|
|
64
|
+
### Upgrade Notes
|
|
65
|
+
- Existing legacy-global text/web/note graph nodes are not rewritten in place.
|
|
66
|
+
Re-ingesting the same content with a workspace id can create a separate
|
|
67
|
+
workspace-scoped node; re-index existing sources after upgrading when you want
|
|
68
|
+
provenance to converge on workspace scopes.
|
|
69
|
+
|
|
11
70
|
## [8.2.0] - 2026-06-27
|
|
12
71
|
|
|
13
72
|
### Added
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Community And Plugins
|
|
2
|
+
|
|
3
|
+
Current release: **8.4.0 - Action-Aware Brain Chat**.
|
|
4
|
+
|
|
5
|
+
LatticeAI 8.4.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.4.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,10 +1,10 @@
|
|
|
1
1
|
# Lattice AI Development
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.4.0 - Action-Aware Brain Chat**.
|
|
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.4.0 in `docs/CHANGELOG.md` and
|
|
8
8
|
`RELEASE.md`.
|
|
9
9
|
|
|
10
10
|
## Product Contract
|
|
@@ -112,10 +112,10 @@ For user-facing, API, runtime, release, or packaging changes, check:
|
|
|
112
112
|
Release/publish examples must use exact target-version filenames. Do not
|
|
113
113
|
document wildcard artifact upload commands.
|
|
114
114
|
|
|
115
|
-
For 8.
|
|
115
|
+
For 8.4.0 release work, exact artifacts are:
|
|
116
116
|
|
|
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.
|
|
117
|
+
- `dist/ltcai-8.4.0-py3-none-any.whl`
|
|
118
|
+
- `dist/ltcai-8.4.0.tar.gz`
|
|
119
|
+
- `ltcai-8.4.0.tgz`
|
|
120
|
+
- `dist/ltcai-8.4.0.vsix`
|
|
121
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_8.4.0_aarch64.dmg`
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
# Legacy Compatibility Map
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.4.0 - Action-Aware Brain Chat**.
|
|
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.4.0 architecture.
|
|
10
|
+
|
|
11
|
+
8.4.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.
|
|
10
19
|
|
|
11
20
|
## Current Policy
|
|
12
21
|
|
|
@@ -17,6 +26,9 @@ current 8.2.0 architecture.
|
|
|
17
26
|
- Add deprecation notes before removal.
|
|
18
27
|
- Avoid breaking package users during a minor release.
|
|
19
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.
|
|
20
32
|
|
|
21
33
|
## Root Module Map
|
|
22
34
|
|
|
@@ -35,6 +47,14 @@ current 8.2.0 architecture.
|
|
|
35
47
|
| `setup_wizard.py` | setup and model recommendation services | Compatibility for first-run recommendation calls |
|
|
36
48
|
| `server.py` | lazy proxy to `latticeai.server_app` / `latticeai.app_factory` | Preserves historical `server.app` imports without import-time construction |
|
|
37
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
|
+
|
|
38
58
|
## Packaging Notes
|
|
39
59
|
|
|
40
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.4.0 - Action-Aware Brain Chat**.
|
|
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.4.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
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.4.0 - Action-Aware Brain Chat**.
|
|
4
4
|
|
|
5
5
|
**Lattice AI is a local-first Digital Brain that keeps your knowledge durable
|
|
6
6
|
across any AI model.**
|
|
@@ -32,9 +32,10 @@ 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.
|
|
36
|
-
conversation composer,
|
|
37
|
-
user immediately knows what matters
|
|
35
|
+
In 8.4.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.
|
|
38
39
|
|
|
39
40
|
## Practical Reasons To Use It
|
|
40
41
|
|
package/docs/kg-schema.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Knowledge Graph Schema
|
|
2
2
|
|
|
3
|
-
Current release: **8.
|
|
3
|
+
Current release: **8.4.0 - Action-Aware Brain Chat**.
|
|
4
4
|
|
|
5
5
|
명세 출처: `lattice_ai_full_spec.pptx` 슬라이드 20·21·22
|
|
6
6
|
구현: `kg_schema.py`
|
|
@@ -90,7 +90,7 @@ Edge {
|
|
|
90
90
|
|
|
91
91
|
## Current Knowledge Graph First 엔티티/관계
|
|
92
92
|
|
|
93
|
-
8.
|
|
93
|
+
8.4.0 은 "모든 데이터 소스가 Knowledge Graph 로 수렴한다"는 원칙을 1급 스키마로
|
|
94
94
|
승격한다. 아래 타입은 **추가형(additive)**이다 — 기존 enum/legacy 매핑을 깨지 않고
|
|
95
95
|
`from_legacy` 가 무손실로 정규화하며, 알 수 없는 타입은 여전히 `CONCEPT`/`MENTIONS` 로
|
|
96
96
|
폴백한다. 스키마는 **확장 가능**하게 유지한다: 새 도메인 엔티티는 enum 멤버 1개 +
|
|
@@ -138,7 +138,7 @@ provenance(source_type, source_uri, content_hash, captured_at, modified_at,
|
|
|
138
138
|
- provenance 는 노드 `metadata.provenance` 에 임베드되며, 동시에 감사 가능한
|
|
139
139
|
`ingestion_provenance` 테이블에 기록된다 (`KnowledgeGraphStore.get_provenance(node_id)`).
|
|
140
140
|
|
|
141
|
-
구현: `
|
|
141
|
+
구현: `lattice_brain/ingestion.py` (`IngestionPipeline`) 가 단일 진입점이며,
|
|
142
142
|
파일/로컬폴더/URL/브라우저 탭/텍스트를 모두 이 형태로 정규화한다.
|
|
143
143
|
|
|
144
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
|
|
|
@@ -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.4.0"
|
|
25
25
|
|
|
26
26
|
AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
|
|
27
27
|
CORE_PIPELINE = ("planner", "executor", "reviewer")
|