ltcai 10.0.0 → 10.2.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 +48 -32
- package/docs/CHANGELOG.md +156 -0
- package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/HYBRID_CLOUD_KG_STREAMING.md +101 -0
- package/docs/ONBOARDING.md +1 -1
- package/docs/OPERATIONS.md +1 -1
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +1 -1
- package/docs/kg-schema.md +1 -1
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/archive.py +5 -4
- package/lattice_brain/conversations.py +14 -3
- package/lattice_brain/embeddings.py +12 -2
- package/lattice_brain/graph/_kg_common.py +5 -5
- package/lattice_brain/graph/_kg_fsutil.py +4 -3
- package/lattice_brain/graph/discovery.py +4 -3
- package/lattice_brain/graph/discovery_index.py +0 -1
- package/lattice_brain/graph/documents.py +3 -2
- package/lattice_brain/graph/fusion.py +4 -0
- package/lattice_brain/graph/ingest.py +12 -2
- package/lattice_brain/graph/projection.py +3 -2
- package/lattice_brain/graph/provenance.py +5 -3
- package/lattice_brain/graph/rerank.py +4 -1
- package/lattice_brain/graph/retrieval.py +0 -1
- package/lattice_brain/graph/retrieval_docgen.py +0 -1
- package/lattice_brain/graph/retrieval_reads.py +0 -1
- package/lattice_brain/graph/retrieval_vector.py +0 -1
- package/lattice_brain/graph/schema.py +4 -3
- package/lattice_brain/graph/store.py +18 -4
- package/lattice_brain/graph/write_master.py +46 -1
- package/lattice_brain/ingestion.py +4 -1
- package/lattice_brain/portability.py +5 -2
- package/lattice_brain/quality.py +12 -5
- package/lattice_brain/quiet.py +43 -0
- package/lattice_brain/runtime/agent_runtime.py +12 -8
- package/lattice_brain/runtime/hooks.py +2 -1
- package/lattice_brain/runtime/multi_agent.py +2 -3
- package/lattice_brain/sensitivity.py +94 -0
- package/lattice_brain/storage/base.py +30 -2
- package/lattice_brain/storage/migration.py +3 -2
- package/lattice_brain/storage/postgres.py +2 -2
- package/lattice_brain/storage/sqlite.py +6 -4
- package/lattice_brain/workflow.py +4 -2
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/admin.py +1 -1
- package/latticeai/api/agents.py +4 -2
- package/latticeai/api/auth.py +5 -1
- package/latticeai/api/automation_intelligence.py +2 -1
- package/latticeai/api/browser.py +3 -2
- package/latticeai/api/chat.py +28 -17
- package/latticeai/api/chat_agent_http.py +22 -8
- package/latticeai/api/chat_contracts.py +4 -0
- package/latticeai/api/chat_documents.py +6 -2
- package/latticeai/api/chat_hybrid.py +82 -0
- package/latticeai/api/computer_use.py +8 -3
- package/latticeai/api/knowledge_graph.py +1 -1
- package/latticeai/api/mcp.py +4 -4
- package/latticeai/api/models.py +5 -2
- package/latticeai/api/network_boundary.py +220 -0
- package/latticeai/api/permissions.py +0 -1
- package/latticeai/api/realtime.py +1 -1
- package/latticeai/api/security_dashboard.py +1 -1
- package/latticeai/api/setup.py +16 -3
- package/latticeai/api/static_routes.py +2 -1
- package/latticeai/api/tools.py +12 -8
- package/latticeai/api/voice_capture.py +3 -1
- package/latticeai/api/workflow_designer.py +1 -1
- package/latticeai/api/workspace.py +1 -2
- package/latticeai/app_factory.py +131 -78
- package/latticeai/cli/entrypoint.py +6 -4
- package/latticeai/core/agent.py +55 -495
- package/latticeai/core/agent_eval.py +2 -2
- package/latticeai/core/agent_helpers.py +493 -0
- package/latticeai/core/agent_prompts.py +0 -1
- package/latticeai/core/agent_registry.py +3 -1
- package/latticeai/core/agent_state.py +41 -0
- package/latticeai/core/audit.py +1 -1
- package/latticeai/core/builtin_hooks.py +2 -1
- package/latticeai/core/config.py +0 -1
- package/latticeai/core/embedding_providers.py +12 -1
- package/latticeai/core/file_generation.py +3 -0
- package/latticeai/core/invitations.py +4 -1
- package/latticeai/core/io_utils.py +3 -1
- package/latticeai/core/legacy_compatibility.py +1 -2
- package/latticeai/core/local_embeddings.py +12 -1
- package/latticeai/core/marketplace.py +1 -2
- package/latticeai/core/mcp_registry.py +0 -1
- package/latticeai/core/model_compat.py +1 -1
- package/latticeai/core/model_resolution.py +1 -1
- package/latticeai/core/network_boundary.py +168 -0
- package/latticeai/core/oidc.py +3 -0
- package/latticeai/core/permission_mode.py +6 -6
- package/latticeai/core/plugins.py +3 -2
- package/latticeai/core/policy.py +0 -1
- package/latticeai/core/quiet.py +84 -0
- package/latticeai/core/realtime.py +3 -2
- package/latticeai/core/run_store.py +4 -2
- package/latticeai/core/security.py +4 -0
- package/latticeai/core/users.py +5 -3
- package/latticeai/core/workspace_graph_trace.py +3 -0
- package/latticeai/core/workspace_os.py +65 -273
- package/latticeai/core/workspace_os_constants.py +126 -0
- package/latticeai/core/workspace_os_state.py +180 -0
- package/latticeai/core/workspace_os_utils.py +3 -1
- package/latticeai/core/workspace_permissions.py +1 -0
- package/latticeai/core/workspace_snapshots.py +3 -1
- package/latticeai/core/workspace_timeline.py +3 -1
- package/latticeai/integrations/telegram_bot.py +25 -16
- package/latticeai/models/router.py +6 -3
- package/latticeai/runtime/access_runtime.py +3 -1
- package/latticeai/runtime/audit_runtime.py +3 -2
- package/latticeai/runtime/chat_wiring.py +4 -1
- package/latticeai/runtime/history_runtime.py +1 -1
- package/latticeai/runtime/lifespan_runtime.py +3 -1
- package/latticeai/runtime/network_boundary_wiring.py +124 -0
- package/latticeai/runtime/persistence_runtime.py +3 -1
- package/latticeai/runtime/router_registration.py +11 -1
- package/latticeai/services/architecture_readiness.py +1 -2
- package/latticeai/services/change_proposals.py +2 -1
- package/latticeai/services/cloud_egress_audit.py +85 -0
- package/latticeai/services/cloud_extraction.py +129 -0
- package/latticeai/services/cloud_streaming.py +266 -0
- package/latticeai/services/cloud_token_guard.py +84 -0
- package/latticeai/services/command_center.py +2 -1
- package/latticeai/services/folder_watch.py +3 -0
- package/latticeai/services/funnel_metrics.py +3 -1
- package/latticeai/services/hybrid_chat.py +265 -0
- package/latticeai/services/hybrid_context.py +228 -0
- package/latticeai/services/hybrid_policy.py +178 -0
- package/latticeai/services/memory_service.py +1 -1
- package/latticeai/services/model_catalog.py +10 -1
- package/latticeai/services/model_engines.py +35 -14
- package/latticeai/services/model_loading.py +3 -2
- package/latticeai/services/model_runtime.py +68 -17
- package/latticeai/services/multimodal_streaming.py +123 -0
- package/latticeai/services/network_boundary_service.py +154 -0
- package/latticeai/services/openai_compatible_adapter.py +100 -0
- package/latticeai/services/p_reinforce.py +4 -0
- package/latticeai/services/platform_runtime.py +9 -4
- package/latticeai/services/process_audit.py +0 -1
- package/latticeai/services/product_readiness.py +1 -1
- package/latticeai/services/run_executor.py +3 -2
- package/latticeai/services/search_service.py +1 -4
- package/latticeai/services/setup_detection.py +2 -1
- package/latticeai/services/tool_dispatch.py +7 -2
- package/latticeai/services/upload_service.py +2 -1
- package/latticeai/setup/auto_setup.py +10 -7
- package/latticeai/setup/wizard.py +15 -11
- package/latticeai/tools/__init__.py +3 -3
- package/latticeai/tools/commands.py +7 -7
- package/latticeai/tools/computer.py +3 -2
- package/latticeai/tools/documents.py +10 -9
- package/latticeai/tools/filesystem.py +7 -4
- package/latticeai/tools/knowledge.py +2 -0
- package/latticeai/tools/local_files.py +1 -1
- package/latticeai/tools/network.py +2 -1
- package/package.json +5 -3
- package/scripts/bench_agent_smoke.py +0 -1
- package/scripts/bench_models.py +0 -1
- package/scripts/brain_quality_eval.py +7 -2
- package/scripts/bump_version.py +2 -1
- package/scripts/check_current_release_docs.mjs +1 -1
- package/scripts/migrate_brain_storage.py +5 -1
- package/scripts/profile_kg.py +2 -7
- package/scripts/verify_hf_model_registry.py +2 -2
- 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 +37 -37
- package/static/app/assets/{Act-BtCREeN1.js → Act-CbdGD-2i.js} +1 -1
- package/static/app/assets/{AdminConsole-TPeeN18T.js → AdminConsole-LgCkXpnf.js} +1 -1
- package/static/app/assets/{Brain-BKs6JAp0.js → Brain-CoPGJI1L.js} +1 -1
- package/static/app/assets/{BrainHome-BPGOvSd6.js → BrainHome-gVnaxSwp.js} +1 -1
- package/static/app/assets/{BrainSignals-CtzQZ15J.js → BrainSignals-ChxAYHtj.js} +1 -1
- package/static/app/assets/{Capture-1_NaHWqB.js → Capture-DBtgkHZg.js} +1 -1
- package/static/app/assets/{CommandPalette-pqvQOXe4.js → CommandPalette-Ovtv5I0Y.js} +1 -1
- package/static/app/assets/{Library-DhvoPvC7.js → Library-CBia2Fvm.js} +1 -1
- package/static/app/assets/{LivingBrain-DlQ20Q75.js → LivingBrain-CNz-6NSd.js} +1 -1
- package/static/app/assets/{ProductFlow-BZvGDRi_.js → ProductFlow-ePX-Y73J.js} +1 -1
- package/static/app/assets/{ReviewCard-BWgI0D2s.js → ReviewCard-C4mpvkwH.js} +1 -1
- package/static/app/assets/System-BvWNK1zc.js +1 -0
- package/static/app/assets/{activity-Dlfk8YC7.js → activity-CiauPV_3.js} +1 -1
- package/static/app/assets/{bot-CDvUB76P.js → bot-Dwct-Q1x.js} +1 -1
- package/static/app/assets/{brain-xczrohrt.js → brain-BKDW1F0T.js} +1 -1
- package/static/app/assets/{button-SOdH3Oyf.js → button-CCB9Kuw7.js} +1 -1
- package/static/app/assets/{circle-pause-CG1ythH4.js → circle-pause-DNa8WHC5.js} +1 -1
- package/static/app/assets/{circle-play-HXwvjS6W.js → circle-play-8jmxn5mf.js} +1 -1
- package/static/app/assets/{cpu-B0d-rGyk.js → cpu-mxvF3V1I.js} +1 -1
- package/static/app/assets/{download-BGIkTQL6.js → download--SmCcx0p.js} +1 -1
- package/static/app/assets/{folder-open-Dst_Z0_K.js → folder-open-D4Wy5roo.js} +1 -1
- package/static/app/assets/{hard-drive-D53MsWkV.js → hard-drive-BwQcSPlS.js} +1 -1
- package/static/app/assets/index-CQWdDU3z.css +2 -0
- package/static/app/assets/{index-C_IrlQMV.js → index-DDV2YZwM.js} +3 -3
- package/static/app/assets/{input-C5m0riF6.js → input-DFhSjmLS.js} +1 -1
- package/static/app/assets/{network-C5a-E5iS.js → network-Bts7VO94.js} +1 -1
- package/static/app/assets/{primitives-vNXYf58F.js → primitives-BuSMEJY8.js} +1 -1
- package/static/app/assets/search-DZzxhWaQ.js +1 -0
- package/static/app/assets/{shield-alert-Cc-WVXqN.js → shield-alert-BfTO6X_G.js} +1 -1
- package/static/app/assets/{textarea-BkZ0EqVO.js → textarea-BjctW1oh.js} +1 -1
- package/static/app/assets/{useFocusTrap-CTtKbAOU.js → useFocusTrap-CE43-LrA.js} +1 -1
- package/static/app/assets/{useQuery-Dx1fi4Wu.js → useQuery-Bv3ejLL5.js} +1 -1
- package/static/app/assets/{users-BFpQXtEF.js → users-CsNqLZAj.js} +1 -1
- package/static/app/assets/{utils-BA_lmW3J.js → utils-KFFdVG_t.js} +2 -2
- package/static/app/assets/workspace-wdCvdyPF.js +1 -0
- package/static/app/index.html +4 -4
- package/static/sw.js +1 -1
- package/static/app/assets/System-CSMdYLMy.js +0 -1
- package/static/app/assets/index-FxDusbr0.css +0 -2
- package/static/app/assets/search-DhbSgW6m.js +0 -1
- package/static/app/assets/workspace-DBPB0jkX.js +0 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://github.com/TaeSooPark-PTS/LatticeAI/actions/workflows/ci.yml)
|
|
12
12
|
[](LICENSE)
|
|
13
13
|
|
|
14
|
-

|
|
15
15
|
|
|
16
16
|
Chat, files, folders, notes, and web pages all flow into one durable knowledge
|
|
17
17
|
graph on your computer. Any model — local MLX or cloud — can speak with that
|
|
@@ -24,9 +24,9 @@ memory. Nothing leaves your machine without explicit consent.
|
|
|
24
24
|
|
|
25
25
|
| | |
|
|
26
26
|
| --- | --- |
|
|
27
|
-
| **Chat with a Brain that remembers** — every conversation grows durable, source-linked memory  | **See how knowledge connects** — a real relationship graph, not a file list  |
|
|
28
|
+
| **Capture anything** — files, whole folders, notes, screenshots, web pages  | **Automate with review** — agent changes become proposals you approve first  |
|
|
29
|
+
| **Pick a model in one click** — recommended local models for your hardware  | **Stay in control** — audit, roles, retention in a separate admin surface  |
|
|
30
30
|
|
|
31
31
|
## Why Lattice AI
|
|
32
32
|
|
|
@@ -57,41 +57,53 @@ First-run flow — wake the Brain, pick the owner, load a recommended model:
|
|
|
57
57
|
|
|
58
58
|
| | | |
|
|
59
59
|
| --- | --- | --- |
|
|
60
|
-
|  |  |  |
|
|
61
61
|
|
|
62
62
|
Screenshot index and capture notes:
|
|
63
|
-
[output/release/v10.
|
|
63
|
+
[output/release/v10.2.0/SCREENSHOT_INDEX.md](output/release/v10.2.0/SCREENSHOT_INDEX.md)
|
|
64
64
|
|
|
65
65
|
## Current Release
|
|
66
66
|
|
|
67
|
-
The current release is **10.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- **
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
- **
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
67
|
+
The current release is **10.2.0 — Load-Bearing Fixes**:
|
|
68
|
+
|
|
69
|
+
A full code review of 10.1.1 scored the codebase 71/100 and found two things
|
|
70
|
+
that were true but invisible. This release is that review's response.
|
|
71
|
+
|
|
72
|
+
- **A database connection leak that hid behind garbage collection.**
|
|
73
|
+
`with sqlite3.connect(...)` commits but never closes, and 70+ call sites
|
|
74
|
+
relied on it. Nothing showed until something held a stack frame alive — a
|
|
75
|
+
profiler, a logged traceback, a coverage tracer — and then descriptors ran
|
|
76
|
+
out. Every one of those sites now closes.
|
|
77
|
+
- **Coverage is measurable for the first time: 71%.** It could not be run
|
|
78
|
+
before, because running it *was* the thing that exhausted descriptors. There
|
|
79
|
+
is now a floor in CI so it cannot silently fall.
|
|
80
|
+
- **"Sensitive memories are never sent" is finally true.** The filter was real,
|
|
81
|
+
correct, and wired — but nothing in the product could mark a memory, and the
|
|
82
|
+
blocked-type list was empty, so it could never fire. You can now mark any
|
|
83
|
+
memory from the boundary panel, files under `.ssh`/`.aws`/`.env` and friends
|
|
84
|
+
are flagged automatically at ingestion, and credential-shaped node types are
|
|
85
|
+
blocked outright.
|
|
86
|
+
- **Knowledge that leaves is now redacted and recorded.** Secret-shaped text is
|
|
87
|
+
stripped from the outbound payload, and every send — and every refusal —
|
|
88
|
+
writes an audit entry naming what went, how much, and where to.
|
|
89
|
+
- **112 silent `except: pass` handlers now say something.** Behaviour is
|
|
90
|
+
unchanged; each records the failure at debug level, so a genuine bug in an
|
|
91
|
+
optional path is no longer indistinguishable from the optional thing being
|
|
92
|
+
absent.
|
|
93
|
+
- **The lint net was widened to the bug classes that actually bit** — loop
|
|
94
|
+
variable capture, truncating `zip`, silent handlers — and mypy now runs on
|
|
95
|
+
the trust-critical modules. CI gained macOS and Python 3.14, so the machine
|
|
96
|
+
this is developed on and the platform it ships a `.dmg` for are both tested.
|
|
85
97
|
|
|
86
98
|
Release notes: [RELEASE.md](RELEASE.md) · Full history: [docs/CHANGELOG.md](docs/CHANGELOG.md)
|
|
87
99
|
|
|
88
|
-
Expected artifacts for 10.
|
|
100
|
+
Expected artifacts for 10.2.0 release must use exact filenames:
|
|
89
101
|
|
|
90
|
-
- `dist/ltcai-10.
|
|
91
|
-
- `dist/ltcai-10.
|
|
92
|
-
- `ltcai-10.
|
|
93
|
-
- `dist/ltcai-10.
|
|
94
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_10.
|
|
102
|
+
- `dist/ltcai-10.2.0-py3-none-any.whl`
|
|
103
|
+
- `dist/ltcai-10.2.0.tar.gz`
|
|
104
|
+
- `ltcai-10.2.0.tgz`
|
|
105
|
+
- `dist/ltcai-10.2.0.vsix`
|
|
106
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_10.2.0_aarch64.dmg`
|
|
95
107
|
|
|
96
108
|
Do not use wildcard artifact uploads. Package registry publishing remains owner-run.
|
|
97
109
|
|
|
@@ -111,7 +123,7 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for details and
|
|
|
111
123
|
|
|
112
124
|
- External package registries are owner-published and can lag behind GitHub.
|
|
113
125
|
- PostgreSQL/pgvector is optional scale/migration tooling. SQLite remains the
|
|
114
|
-
live local Brain store in 10.
|
|
126
|
+
live local Brain store in 10.2.0.
|
|
115
127
|
- Docker, model downloads, cloud model calls, Telegram, Brain Network, and
|
|
116
128
|
update checks require explicit user action.
|
|
117
129
|
- Conversation does not fabricate answers when no model is loaded. Agent and
|
|
@@ -120,12 +132,16 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) for details and
|
|
|
120
132
|
model success.
|
|
121
133
|
- Some backend-generated messages (for example the Postgres DSN notice) are
|
|
122
134
|
produced server-side in English and are shown as-is; server-side i18n is not
|
|
123
|
-
part of 10.
|
|
135
|
+
part of 10.2.0.
|
|
124
136
|
|
|
125
137
|
## Release History
|
|
126
138
|
|
|
127
139
|
| Version | Theme |
|
|
128
140
|
| --- | --- |
|
|
141
|
+
| 10.2.0 | Load-Bearing Fixes |
|
|
142
|
+
| 10.1.1 | Reachable Boundary |
|
|
143
|
+
| 10.1.0 | Hybrid Brain |
|
|
144
|
+
| 10.0.1 | One Source of Truth |
|
|
129
145
|
| 10.0.0 | Plain Language |
|
|
130
146
|
| 9.9.9 | Lean Shell |
|
|
131
147
|
| 9.9.8 | Autonomy Dial |
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,162 @@ The top entry is either the current unreleased main-branch work or the current
|
|
|
4
4
|
release line. Older entries are historical and may describe behavior as it
|
|
5
5
|
existed at that release.
|
|
6
6
|
|
|
7
|
+
## [10.2.0] - 2026-07-29
|
|
8
|
+
|
|
9
|
+
Response to a full code review of 10.1.1 (71/100). All twelve findings.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- **SQLite connections were committed but never closed** at 70+ sites.
|
|
13
|
+
`sqlite3.Connection.__exit__` commits or rolls back and leaves the connection
|
|
14
|
+
open; `KnowledgeGraphStore._connect`, `ConversationStore._connect`,
|
|
15
|
+
`WorkspaceOSStore._connect_state_db`, both storage engines, `portability`,
|
|
16
|
+
`archive`, `migration` and `users` all relied on it. Refcounting hid the leak
|
|
17
|
+
until something held a frame alive (profiler, logged traceback, coverage
|
|
18
|
+
tracer), at which point the process hit `EMFILE`. Added
|
|
19
|
+
`StorageEngine.session()` and made the store helpers closing context
|
|
20
|
+
managers; `tests/unit/test_connection_lifecycle.py` asserts it.
|
|
21
|
+
- **The cloud sensitivity guard could not fire.** `HARD_BLOCK_NODE_TYPES` was
|
|
22
|
+
an empty set and nothing in the product could set the metadata flags
|
|
23
|
+
`is_node_blocked_for_cloud` matches on, so "sensitive memories are never
|
|
24
|
+
sent" was unfalsifiable. Populated the type list, added
|
|
25
|
+
`lattice_brain/sensitivity.py` (path rules, stamped at ingestion), added
|
|
26
|
+
`KnowledgeGraphStore.set_node_sensitivity` and
|
|
27
|
+
`POST /api/network-boundary/node-sensitivity`, and a per-memory hold-back
|
|
28
|
+
control in the boundary panel.
|
|
29
|
+
- **Outbound cloud text was not redacted.** `redact_secret_text` ran on logs,
|
|
30
|
+
audit records and API previews but not on the payload that actually leaves.
|
|
31
|
+
- **Vector similarity truncated silently on a dimension mismatch**, producing a
|
|
32
|
+
plausible but meaningless score. Now raises with both dimensions named.
|
|
33
|
+
- **`tempfile.mktemp()` (TOCTOU race) in the Telegram bridge** replaced with
|
|
34
|
+
`mkstemp` at two sites.
|
|
35
|
+
- **Three closures captured loop variables by reference** (`chat_agent_http`,
|
|
36
|
+
`computer_use`, `model_runtime`). Safe today because each is invoked within
|
|
37
|
+
its iteration; bound explicitly so deferring the call cannot break them.
|
|
38
|
+
- **The cloud turn ran retrieval twice**, discarding the first result except
|
|
39
|
+
for its quality dict.
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
- `latticeai/services/cloud_egress_audit.py` — every cloud send and every
|
|
43
|
+
refusal writes an audit entry *before* the provider call, naming node ids,
|
|
44
|
+
count, token estimate, provider and mode. Shape, never content.
|
|
45
|
+
- `latticeai/core/quiet.py` + `lattice_brain/quiet.py` — `quiet()` keeps the
|
|
46
|
+
behaviour of `except: pass` and records the exception with its file,
|
|
47
|
+
function and line at DEBUG. 112 handlers converted; `except: pass` is now a
|
|
48
|
+
lint error (S110/S112).
|
|
49
|
+
- Coverage measurement: `pytest-cov` in the `dev` extra, `[tool.coverage]`
|
|
50
|
+
config, a **70% floor** in CI. Measured **71%** — the first known figure.
|
|
51
|
+
- `tests/unit/test_cloud_egress_guard.py` — end-to-end proof that a flagged
|
|
52
|
+
memory never reaches the payload, that retrieval still carries `metadata`
|
|
53
|
+
(whose loss would silently disable the filter), and that egress is audited.
|
|
54
|
+
- mypy over 13 trust-critical modules (`npm run typecheck:python`), wired into
|
|
55
|
+
`npm run lint:python`.
|
|
56
|
+
- CI matrix: macOS runner (the platform the `.dmg` ships for, previously
|
|
57
|
+
untested) and Python 3.14 (the version this is developed on).
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
- ruff widened from pyflakes-only to `E4,E7,E9,F,B,S,I,SIM,RET,C901`. Every
|
|
61
|
+
remaining finding is either fixed or carries a written reason; complexity
|
|
62
|
+
ceiling set to 30 with named exemptions.
|
|
63
|
+
- `latticeai/core/workspace_os.py` 1354 → 1130 lines; vocabulary moved to
|
|
64
|
+
`workspace_os_constants.py` and state/migration to `workspace_os_state.py`,
|
|
65
|
+
with delegating methods so the public surface is unchanged.
|
|
66
|
+
- Package classifiers now advertise Python 3.13 and 3.14, matching what CI tests.
|
|
67
|
+
|
|
68
|
+
### Known
|
|
69
|
+
- `app_factory._build` remains one 1,343-line function. Its sections share ~34
|
|
70
|
+
local bindings, so decomposition requires a runtime-context object rather
|
|
71
|
+
than a mechanical extraction; deferred rather than rushed, and named in the
|
|
72
|
+
C901 exemptions so the choice is visible.
|
|
73
|
+
|
|
74
|
+
## [10.1.1] - 2026-07-28
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- `NetworkBoundaryPanel` (`frontend/src/components/NetworkBoundaryPanel.tsx`),
|
|
78
|
+
mounted in the System settings tab beside `PermissionModePanel`. Renders the
|
|
79
|
+
server's mode catalog, gates `cloud_allowed` behind the acknowledgement the
|
|
80
|
+
server requires, and exposes the hybrid write-back policy switches only while
|
|
81
|
+
the boundary permits cloud.
|
|
82
|
+
- Context preview in that panel: a question is sent to
|
|
83
|
+
`POST /api/network-boundary/preview` and the panel lists the actual node
|
|
84
|
+
titles that would leave, the token estimate, and the token guard's verdict.
|
|
85
|
+
Available in `local_only` too, labelled as hypothetical.
|
|
86
|
+
- API client bindings and types: `networkBoundary`, `setNetworkBoundary`,
|
|
87
|
+
`setHybridPolicy`, `previewCloudContext`; `NetworkBoundaryOption`,
|
|
88
|
+
`NetworkBoundaryState`, `HybridPolicy`, `CloudContextPreview`,
|
|
89
|
+
`CloudTokenBudget`. The `networkBoundary` fallback is `local_only`, so a
|
|
90
|
+
failed read never renders as if cloud were already permitted.
|
|
91
|
+
- 22 `system.network.*` copy keys in the `workspace` i18n namespace (ko + en).
|
|
92
|
+
- `/api/network-boundary*` routes in `tests/visual/mock_server.cjs` so release
|
|
93
|
+
evidence shows the panel working rather than an unavailable state.
|
|
94
|
+
- `NetworkBoundaryPanel.test.tsx` (12 tests) and two Playwright specs covering
|
|
95
|
+
the settings-tab route, the acknowledgement gate, and the preview.
|
|
96
|
+
|
|
97
|
+
### Removed
|
|
98
|
+
- `static/app/network-boundary-panel.js` — the unmounted standalone module
|
|
99
|
+
10.1.0 shipped as this feature's UI. Nothing referenced it, it was absent
|
|
100
|
+
from the asset manifest, and it lived in Vite's output directory, which
|
|
101
|
+
`npm run build:assets` wipes; it had in fact already been deleted by the
|
|
102
|
+
previous release's asset rebuild. The React panel replaces it.
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
- ARCHITECTURE, FEATURE_STATUS, README, and the hybrid design doc no longer
|
|
106
|
+
carry the "API-only surface" caveat, and describe the in-app control instead.
|
|
107
|
+
|
|
108
|
+
## [10.1.0] - 2026-07-28
|
|
109
|
+
|
|
110
|
+
### Added
|
|
111
|
+
- Local-first hybrid path: the Knowledge Graph stays on-device and cloud LLMs
|
|
112
|
+
are an opt-in worker. `NetworkBoundaryMode` and `MinimalContext` contracts
|
|
113
|
+
(`latticeai/core/network_boundary.py`, `latticeai/api/network_boundary.py`)
|
|
114
|
+
with a persisted dial wired via `latticeai/runtime/network_boundary_wiring.py`.
|
|
115
|
+
- Cloud streaming worker: `latticeai/services/cloud_streaming.py`,
|
|
116
|
+
`cloud_extraction.py`, `cloud_token_guard.py`, and an OpenAI-compatible stream
|
|
117
|
+
adapter (`openai_compatible_adapter.py`) with token budgets and guardrails.
|
|
118
|
+
- Hybrid chat pipeline: `latticeai/api/chat_hybrid.py` plus
|
|
119
|
+
`services/hybrid_chat.py`, `hybrid_context.py`, and `hybrid_policy.py`; the
|
|
120
|
+
`/chat` route branches through it and writes back through the Review Queue.
|
|
121
|
+
- Multimodal streaming contracts (`services/multimodal_streaming.py`) and a
|
|
122
|
+
network-boundary control panel (`static/app/network-boundary-panel.js`).
|
|
123
|
+
- Tests: `test_network_boundary.py`, `test_hybrid_phase2.py`,
|
|
124
|
+
`test_hybrid_phase3.py`.
|
|
125
|
+
|
|
126
|
+
### Notes
|
|
127
|
+
- Default network boundary is `local_only`; cloud requires explicit
|
|
128
|
+
acknowledgement. Minimal related nodes only leave the machine; streamed
|
|
129
|
+
answers expand the local Brain with provenance.
|
|
130
|
+
|
|
131
|
+
## [10.0.1] - 2026-07-28
|
|
132
|
+
|
|
133
|
+
### Changed
|
|
134
|
+
- `latticeai/core/agent.py` holds only the state machine (1769 → 1326 lines).
|
|
135
|
+
Its pure functions move to `latticeai/core/agent_helpers.py`: action parsing
|
|
136
|
+
(`extract_action`, `extract_action_details`), plan normalization
|
|
137
|
+
(`normalize_plan`), learning filters, transcript compaction, artifact and
|
|
138
|
+
requirement reporting, and the `TranscriptBudget` / `PhaseBudgets` dataclasses.
|
|
139
|
+
- `AgentState` and `AGENT_TERMINAL_STATES` move to a new
|
|
140
|
+
`latticeai/core/agent_state.py`. Both `agent.py` and `agent_helpers.py` import
|
|
141
|
+
from it, which is what lets the helpers reference the enum instead of a
|
|
142
|
+
literal state string.
|
|
143
|
+
- `latticeai.core.agent` re-exports every moved name as the same object and
|
|
144
|
+
declares the set in `__all__`. No caller changed: the HTTP layer, `run_store`,
|
|
145
|
+
`computer_use`, `bench_agent_smoke`, `bench_models`, and eight test modules
|
|
146
|
+
import exactly as before.
|
|
147
|
+
- The home's secondary control row is visually demoted (opacity, tighter gaps,
|
|
148
|
+
softer divider) and gets larger touch spacing under 640px. The sticky top bar
|
|
149
|
+
border is softened. CSS only.
|
|
150
|
+
|
|
151
|
+
### Fixed
|
|
152
|
+
- `files_written` and `artifact_checklist` matched transcript steps against the
|
|
153
|
+
literal `"EXECUTING"` instead of `AgentState.EXECUTING.value`. A rename of the
|
|
154
|
+
enum value would have made both silently return empty results with no failing
|
|
155
|
+
test. Both now reference the enum.
|
|
156
|
+
|
|
157
|
+
### Verification
|
|
158
|
+
- pytest 1747 passed / 11 skipped; `scripts/agent_eval.py` 23/23 (100%); ruff
|
|
159
|
+
clean across `latticeai/`, `lattice_brain/`, `scripts/`, `tests/`.
|
|
160
|
+
- All 18 extracted symbols were AST-compared against their originals before the
|
|
161
|
+
originals were removed.
|
|
162
|
+
|
|
7
163
|
## [10.0.0] - 2026-07-28
|
|
8
164
|
|
|
9
165
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Community And Plugins
|
|
2
2
|
|
|
3
|
-
Current release: **10.
|
|
3
|
+
Current release: **10.2.0 — Load-Bearing Fixes**.
|
|
4
4
|
|
|
5
5
|
LatticeAI defines the path from a strong local-first framework (8.4.0
|
|
6
6
|
action-aware baseline, 8.5.0 registry+DI hardening, 8.6.0 capture/navigation
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Status: canonical** — current contributor guidance, kept in sync with the
|
|
4
4
|
> current release.
|
|
5
5
|
|
|
6
|
-
Current release: **10.
|
|
6
|
+
Current release: **10.2.0 — Load-Bearing Fixes**.
|
|
7
7
|
|
|
8
8
|
This document is for contributors working on the local-first Digital Brain
|
|
9
9
|
codebase. Product positioning and quick start stay in `README.md`; release
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Hybrid Cloud + Local Knowledge Graph Streaming
|
|
2
|
+
|
|
3
|
+
> Status: **shipped in 10.1.0**; in-app control added in **10.1.1**
|
|
4
|
+
> Principle: **Local Brain is the asset. Cloud is an opt-in worker.**
|
|
5
|
+
> Surface: `환경설정 → 내 지식이 나가는 범위`
|
|
6
|
+
> (`frontend/src/components/NetworkBoundaryPanel.tsx`), plus
|
|
7
|
+
> `/api/network-boundary` and `LATTICEAI_NETWORK_MODE`.
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
Local Knowledge Graph stays on-device. Cloud LLMs (and optional multimodal) are opt-in workers. Minimal related nodes leave the machine; streamed answers expand the local Brain with provenance and review gates.
|
|
12
|
+
|
|
13
|
+
## Phase summary
|
|
14
|
+
|
|
15
|
+
| Phase | Branch | Delivered |
|
|
16
|
+
|-------|--------|-----------|
|
|
17
|
+
| 0 | `feature/hybrid-cloud-kg-streaming` | Architecture + core contracts |
|
|
18
|
+
| 1 | `…-phase1` | Dial, OpenAI adapter, hybrid helpers, basic expansion |
|
|
19
|
+
| 2 | `…-phase2` | `/chat` branch, token guardrails, extraction, preview API |
|
|
20
|
+
| **3** | `…-phase3` | **Policy, Review Queue write path, multimodal contracts, UI panel module** |
|
|
21
|
+
|
|
22
|
+
## Phase 3 details
|
|
23
|
+
|
|
24
|
+
### Hybrid policy (`HybridPolicyService`)
|
|
25
|
+
Persisted dial for:
|
|
26
|
+
- `blocked_node_types` / `blocked_metadata_flags` (unioned with hard circuit breakers)
|
|
27
|
+
- `auto_commit` (default **false**)
|
|
28
|
+
- `allow_multimodal` (default **false**)
|
|
29
|
+
- `min_extraction_confidence`
|
|
30
|
+
|
|
31
|
+
API:
|
|
32
|
+
```
|
|
33
|
+
GET /api/network-boundary/policy
|
|
34
|
+
POST /api/network-boundary/policy
|
|
35
|
+
{ "auto_commit": false, "allow_multimodal": false, "blocked_node_types": ["Secret"] }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Review Queue write path
|
|
39
|
+
`CloudResponseIngestor` now:
|
|
40
|
+
1. Always enqueues a `change_proposal` review item when a ReviewQueueService is bound
|
|
41
|
+
2. Only auto-writes to the graph when `plan.auto_commit` is true **and** a store write API exists
|
|
42
|
+
|
|
43
|
+
Users approve cloud-derived memory growth in the existing Review Center.
|
|
44
|
+
|
|
45
|
+
### Multimodal / video
|
|
46
|
+
`latticeai/services/multimodal_streaming.py`:
|
|
47
|
+
- Same `NetworkBoundaryMode.CLOUD_ALLOWED` gate
|
|
48
|
+
- Additional `allow_multimodal` policy flag
|
|
49
|
+
- Adapter protocol for future Runway/Luma/Veo-compatible providers
|
|
50
|
+
|
|
51
|
+
### UI
|
|
52
|
+
`NetworkBoundaryPanel` (React) + `GET /api/network-boundary/ui-state`:
|
|
53
|
+
- Toggle local ↔ cloud (with ack)
|
|
54
|
+
- Transparency preview of nodes about to be sent
|
|
55
|
+
- Shows current policy flags
|
|
56
|
+
|
|
57
|
+
Mounted in `frontend/src/pages/System.tsx` beside `PermissionModePanel`, so it
|
|
58
|
+
appears on the settings tab of every install. The standalone
|
|
59
|
+
`static/app/network-boundary-panel.js` module 10.1.0 shipped was removed in
|
|
60
|
+
10.1.1: nothing mounted it, and it lived in Vite's build output directory,
|
|
61
|
+
which `npm run build:assets` wipes.
|
|
62
|
+
|
|
63
|
+
## End-to-end flow (Phase 3)
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
User toggles cloud_allowed (UI panel or API)
|
|
67
|
+
→ optional policy: auto_commit / multimodal / sensitivity
|
|
68
|
+
User sends chat message
|
|
69
|
+
→ /chat resolves mode
|
|
70
|
+
→ if cloud_allowed: minimal KG context + token budget check
|
|
71
|
+
→ cloud stream (SSE)
|
|
72
|
+
→ rich extraction (Decision/Task/Concept)
|
|
73
|
+
→ Review Queue item (change_proposal)
|
|
74
|
+
→ optional auto-commit when policy allows
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Configuration
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
export LATTICEAI_CLOUD_API_KEY=sk-...
|
|
81
|
+
export LATTICEAI_CLOUD_MODEL=gpt-4o-mini
|
|
82
|
+
export LATTICEAI_NETWORK_MODE=local_only
|
|
83
|
+
export LATTICEAI_CLOUD_MAX_TOKENS_PER_TURN=2500
|
|
84
|
+
export LATTICEAI_CLOUD_MAX_TOKENS_PER_SESSION=50000
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Privacy (unchanged core rules)
|
|
88
|
+
|
|
89
|
+
1. Default `local_only`
|
|
90
|
+
2. Cloud requires explicit ack
|
|
91
|
+
3. Only minimal compact context leaves the host
|
|
92
|
+
4. Hard + user sensitivity filters
|
|
93
|
+
5. Cloud-derived nodes go through Review Queue unless user opts into auto_commit
|
|
94
|
+
6. Multimodal is off unless policy explicitly enables it
|
|
95
|
+
|
|
96
|
+
## Success criteria (Phase 3)
|
|
97
|
+
|
|
98
|
+
- User can configure sensitivity and auto-commit without code changes
|
|
99
|
+
- Cloud KG growth appears in Review Center as actionable proposals
|
|
100
|
+
- Multimodal path cannot fire without both cloud mode and policy flag
|
|
101
|
+
- UI panel works without rebuilding the main React bundle
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Lattice AI Onboarding
|
|
2
2
|
|
|
3
|
-
Current release: **10.
|
|
3
|
+
Current release: **10.2.0 — Load-Bearing Fixes**.
|
|
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
|
package/docs/OPERATIONS.md
CHANGED
package/docs/TRUST_MODEL.md
CHANGED
package/docs/WHY_LATTICE.md
CHANGED
package/docs/kg-schema.md
CHANGED
package/lattice_brain/archive.py
CHANGED
|
@@ -16,17 +16,18 @@ import shutil
|
|
|
16
16
|
import sqlite3
|
|
17
17
|
import tempfile
|
|
18
18
|
import zipfile
|
|
19
|
+
from contextlib import closing
|
|
19
20
|
from dataclasses import dataclass
|
|
20
21
|
from pathlib import Path, PurePosixPath
|
|
21
22
|
from typing import Any, Dict, Iterable, List, Optional
|
|
22
23
|
|
|
24
|
+
from cryptography.exceptions import InvalidTag
|
|
23
25
|
from cryptography.hazmat.primitives import hashes
|
|
24
26
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
25
|
-
from cryptography.exceptions import InvalidTag
|
|
26
27
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
27
28
|
|
|
28
|
-
from .utils import sha256_file as _sha256_file
|
|
29
|
-
|
|
29
|
+
from .utils import sha256_file as _sha256_file
|
|
30
|
+
from .utils import utc_now_iso as _now
|
|
30
31
|
|
|
31
32
|
ARCHIVE_FORMAT = "latticebrain.encrypted"
|
|
32
33
|
ARCHIVE_VERSION = 2
|
|
@@ -106,7 +107,7 @@ def _checkpoint_sqlite(db_path: Path) -> None:
|
|
|
106
107
|
if not db_path.exists():
|
|
107
108
|
return
|
|
108
109
|
try:
|
|
109
|
-
with sqlite3.connect(str(db_path)) as conn:
|
|
110
|
+
with closing(sqlite3.connect(str(db_path))) as conn, conn:
|
|
110
111
|
conn.execute("PRAGMA wal_checkpoint(FULL)")
|
|
111
112
|
except sqlite3.Error:
|
|
112
113
|
return
|
|
@@ -19,8 +19,9 @@ import json
|
|
|
19
19
|
import logging
|
|
20
20
|
import sqlite3
|
|
21
21
|
import threading
|
|
22
|
+
from contextlib import contextmanager
|
|
22
23
|
from pathlib import Path
|
|
23
|
-
from typing import Any, Dict, List, Optional
|
|
24
|
+
from typing import Any, Dict, Iterator, List, Optional
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def _message_hash(item: Dict[str, Any]) -> str:
|
|
@@ -40,11 +41,21 @@ class ConversationStore:
|
|
|
40
41
|
self._lock = threading.RLock()
|
|
41
42
|
self._init_db()
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
@contextmanager
|
|
45
|
+
def _connect(self) -> Iterator[sqlite3.Connection]:
|
|
46
|
+
"""Transactional connection that is closed when the block exits.
|
|
47
|
+
|
|
48
|
+
``with sqlite3.connect(...)`` commits but never closes; see
|
|
49
|
+
:meth:`lattice_brain.storage.base.StorageEngine.session`.
|
|
50
|
+
"""
|
|
44
51
|
conn = sqlite3.connect(str(self.db_path))
|
|
45
52
|
conn.row_factory = sqlite3.Row
|
|
46
53
|
conn.execute("PRAGMA journal_mode=WAL")
|
|
47
|
-
|
|
54
|
+
try:
|
|
55
|
+
with conn:
|
|
56
|
+
yield conn
|
|
57
|
+
finally:
|
|
58
|
+
conn.close()
|
|
48
59
|
|
|
49
60
|
def _init_db(self) -> None:
|
|
50
61
|
with self._lock, self._connect() as conn:
|
|
@@ -10,7 +10,6 @@ import struct
|
|
|
10
10
|
from dataclasses import dataclass
|
|
11
11
|
from typing import Any, Dict, Iterable, List, Optional
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
DEFAULT_EMBEDDING_DIM = int(os.getenv("LATTICEAI_VECTOR_DIM", "384"))
|
|
15
14
|
EMBEDDING_MODEL_ID = f"lattice-local-hash-v1:{DEFAULT_EMBEDDING_DIM}"
|
|
16
15
|
|
|
@@ -71,7 +70,18 @@ class LocalEmbeddingModel:
|
|
|
71
70
|
return [value / norm for value in vector]
|
|
72
71
|
|
|
73
72
|
def similarity(self, left: Iterable[float], right: Iterable[float]) -> float:
|
|
74
|
-
|
|
73
|
+
# strict=True: a dimension mismatch means the two vectors came from
|
|
74
|
+
# different embedding models. Truncating to the shorter one produces a
|
|
75
|
+
# plausible-looking similarity that is meaningless — exactly the silent
|
|
76
|
+
# wrongness this codebase keeps finding. Callers that can hit a model
|
|
77
|
+
# swap already handle failure and fall back to lexical search.
|
|
78
|
+
left_v, right_v = list(left), list(right)
|
|
79
|
+
if len(left_v) != len(right_v):
|
|
80
|
+
raise ValueError(
|
|
81
|
+
f"embedding dimension mismatch: {len(left_v)} vs {len(right_v)}; "
|
|
82
|
+
"the vector index was built with a different model"
|
|
83
|
+
)
|
|
84
|
+
return float(sum(a * b for a, b in zip(left_v, right_v, strict=True)))
|
|
75
85
|
|
|
76
86
|
def encode(self, vector: Iterable[float]) -> bytes:
|
|
77
87
|
values = list(vector)
|
|
@@ -21,12 +21,13 @@ import sqlite3
|
|
|
21
21
|
import time
|
|
22
22
|
import zipfile
|
|
23
23
|
from collections import Counter
|
|
24
|
+
from contextlib import contextmanager
|
|
24
25
|
from datetime import datetime
|
|
25
26
|
from pathlib import Path
|
|
26
|
-
from typing import Any, Dict, Iterable, List, Optional, Tuple
|
|
27
|
+
from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple
|
|
27
28
|
|
|
28
29
|
try:
|
|
29
|
-
from .schema import KGStoreV2, NodeType,
|
|
30
|
+
from .schema import EdgeType, KGStoreV2, NodeType, _exec_script
|
|
30
31
|
except Exception: # pragma: no cover - v2 schema is optional at import time
|
|
31
32
|
KGStoreV2 = None # type: ignore[assignment]
|
|
32
33
|
NodeType = None # type: ignore[assignment]
|
|
@@ -44,6 +45,7 @@ _READ_FROM_V2_DEFAULT = os.getenv("LATTICEAI_KG_READ_V2", "1") != "0"
|
|
|
44
45
|
# Static constants (projection/format versions, local-ingestion classification
|
|
45
46
|
# tables, OS exclusion lists) live in ._kg_constants; re-exported here so every
|
|
46
47
|
# existing ``from ._kg_common import <CONST>`` site is unaffected.
|
|
48
|
+
from ..quiet import quiet
|
|
47
49
|
from ._kg_constants import ( # noqa: E402
|
|
48
50
|
_KG_DB_FORMAT_KEY,
|
|
49
51
|
_KG_DB_FORMAT_VERSION,
|
|
@@ -67,7 +69,6 @@ from ._kg_constants import ( # noqa: E402
|
|
|
67
69
|
WINDOWS_EXCLUDED_NAMES,
|
|
68
70
|
)
|
|
69
71
|
|
|
70
|
-
|
|
71
72
|
# Pure fs/path/hash/classification helpers → ._kg_fsutil (re-exported so the
|
|
72
73
|
# computed __all__ below still forwards them to the graph mixins).
|
|
73
74
|
from ._kg_fsutil import * # noqa: E402,F401,F403
|
|
@@ -152,7 +153,7 @@ def chunk_strategy_for(filename: Any, *, content_type: str = "") -> str:
|
|
|
152
153
|
if mime.startswith("text/html") or mime.startswith("text/plain"):
|
|
153
154
|
return "prose"
|
|
154
155
|
except Exception:
|
|
155
|
-
|
|
156
|
+
quiet()
|
|
156
157
|
return "plain"
|
|
157
158
|
|
|
158
159
|
|
|
@@ -736,7 +737,6 @@ _CONCEPT_STOP: set = {
|
|
|
736
737
|
"yes",
|
|
737
738
|
"not",
|
|
738
739
|
"but",
|
|
739
|
-
"are",
|
|
740
740
|
"all",
|
|
741
741
|
"any",
|
|
742
742
|
"out",
|
|
@@ -11,7 +11,6 @@ them to the graph mixins), so existing call sites are unaffected.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
# ruff: noqa: F403,F405
|
|
14
|
-
|
|
15
14
|
import hashlib
|
|
16
15
|
import math
|
|
17
16
|
import os
|
|
@@ -21,8 +20,10 @@ from datetime import datetime
|
|
|
21
20
|
from pathlib import Path
|
|
22
21
|
from typing import Any, Dict, List, Optional, Tuple
|
|
23
22
|
|
|
23
|
+
from ..quiet import quiet
|
|
24
|
+
from ..utils import now_iso as _now
|
|
25
|
+
from ..utils import parse_iso as _parse_iso
|
|
24
26
|
from ._kg_constants import * # noqa: F401,F403
|
|
25
|
-
from ..utils import now_iso as _now, parse_iso as _parse_iso
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def _recency_score(
|
|
@@ -202,7 +203,7 @@ def _excluded_directory_reason(
|
|
|
202
203
|
):
|
|
203
204
|
return "user_library"
|
|
204
205
|
except OSError:
|
|
205
|
-
|
|
206
|
+
quiet()
|
|
206
207
|
if _prefix_blocks(MACOS_EXCLUDED_PREFIXES):
|
|
207
208
|
return "system_folder"
|
|
208
209
|
if os_type == "linux":
|