ltcai 6.4.0 → 6.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -28
- package/docs/CHANGELOG.md +62 -0
- package/frontend/openapi.json +65 -1
- package/frontend/src/api/client.ts +2 -0
- package/frontend/src/api/openapi.ts +86 -0
- package/frontend/src/features/brain/BrainComposer.tsx +20 -1
- package/frontend/src/features/brain/BrainConversation.tsx +48 -4
- package/frontend/src/features/brain/BrainHome.tsx +61 -1
- package/frontend/src/features/brain/BrainMemoryLayer.tsx +8 -1
- package/frontend/src/features/brain/BrainOverviewPanel.tsx +76 -1
- package/frontend/src/features/brain/brainData.ts +125 -1
- package/frontend/src/features/brain/types.ts +52 -0
- package/frontend/src/i18n.ts +66 -0
- package/frontend/src/styles.css +261 -0
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/graph/ingest.py +41 -6
- package/lattice_brain/ingestion.py +1 -0
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/knowledge_graph.py +11 -0
- package/latticeai/api/memory.py +20 -0
- package/latticeai/app_factory.py +2 -0
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/latticeai/runtime/chat_wiring.py +2 -0
- package/latticeai/runtime/router_registration.py +3 -0
- package/latticeai/services/memory_service.py +188 -2
- package/latticeai/services/router_context.py +1 -0
- package/latticeai/services/upload_service.py +12 -0
- package/package.json +1 -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 +5 -5
- package/static/app/assets/{index-Div5vMlq.css → index-C8toxDpv.css} +1 -1
- package/static/app/assets/index-CbvcAQ6B.js +16 -0
- package/static/app/assets/index-CbvcAQ6B.js.map +1 -0
- package/static/app/index.html +2 -2
- package/static/app/assets/index-t1jx1BR9.js +0 -16
- package/static/app/assets/index-t1jx1BR9.js.map +0 -1
package/README.md
CHANGED
|
@@ -69,42 +69,42 @@ You need Lattice AI when:
|
|
|
69
69
|
Choose the owner of the Brain. The profile is not a SaaS account by default; it
|
|
70
70
|
is the local identity for the knowledge you keep.
|
|
71
71
|
|
|
72
|
-

|
|
73
73
|
|
|
74
74
|
### 2. Environment Analysis
|
|
75
75
|
|
|
76
76
|
See what kind of local AI experience this computer can support before choosing a
|
|
77
77
|
model.
|
|
78
78
|
|
|
79
|
-

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

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

|
|
94
94
|
|
|
95
95
|
### 5. Brain Chat
|
|
96
96
|
|
|
97
97
|
Talk normally. Useful decisions and context become memory, then appear later as
|
|
98
98
|
topics, relationships, and graph structure.
|
|
99
99
|
|
|
100
|
-

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

|
|
108
108
|
|
|
109
109
|
## Brain Depths
|
|
110
110
|
|
|
@@ -120,10 +120,10 @@ The user travels inward from everyday memory to deeper structure:
|
|
|
120
120
|
|
|
121
121
|
Walkthrough:
|
|
122
122
|
|
|
123
|
-

|
|
124
124
|
|
|
125
125
|
Screenshot index and capture notes:
|
|
126
|
-
[output/release/v6.
|
|
126
|
+
[output/release/v6.5.0/SCREENSHOT_INDEX.md](output/release/v6.5.0/SCREENSHOT_INDEX.md)
|
|
127
127
|
|
|
128
128
|
## Install
|
|
129
129
|
|
|
@@ -200,31 +200,32 @@ See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for developer workflow details.
|
|
|
200
200
|
|
|
201
201
|
## Current Release Preparation
|
|
202
202
|
|
|
203
|
-
The current development target is **6.
|
|
204
|
-
|
|
205
|
-
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
203
|
+
The current development target is **6.6.0 Brain Proof Runtime**:
|
|
204
|
+
|
|
205
|
+
- Brain Home now shows backend-owned proof that the Brain is a durable context
|
|
206
|
+
store: saved context count, active-model continuity, graph/vector depth, and
|
|
207
|
+
the most recent recallable item.
|
|
208
|
+
- Brain Home now gives first-time users a direct document upload CTA in the
|
|
209
|
+
empty state and composer, backed by workspace-scoped document ingestion.
|
|
210
|
+
- `/api/memory/brain-proof` combines Memory Manager readiness, unified recall,
|
|
211
|
+
graph/vector state, and the active model id so the first screen can say
|
|
212
|
+
"model changed, context stayed" without guessing in the frontend.
|
|
213
|
+
- App-factory interaction wiring now passes active-model state into the Memory
|
|
214
|
+
router through typed runtime context, keeping Brain proof assembly out of the
|
|
215
|
+
monolithic factory body.
|
|
216
|
+
- The release keeps the 6.4.0/6.5.0 Brain readiness and quality hardening intact
|
|
217
|
+
while making the first-five-minute value proposition visible.
|
|
217
218
|
- The release remains local-first: no automatic web/email/calendar ingestion,
|
|
218
219
|
no package publishing, no production deployment, and no external reranker or
|
|
219
220
|
embedding API use without explicit opt-in.
|
|
220
221
|
|
|
221
|
-
Expected artifacts for 6.
|
|
222
|
+
Expected artifacts for 6.6.0 release must use exact filenames:
|
|
222
223
|
|
|
223
|
-
- `dist/ltcai-6.
|
|
224
|
-
- `dist/ltcai-6.
|
|
225
|
-
- `ltcai-6.
|
|
226
|
-
- `dist/ltcai-6.
|
|
227
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_6.
|
|
224
|
+
- `dist/ltcai-6.6.0-py3-none-any.whl`
|
|
225
|
+
- `dist/ltcai-6.6.0.tar.gz`
|
|
226
|
+
- `ltcai-6.6.0.tgz`
|
|
227
|
+
- `dist/ltcai-6.6.0.vsix`
|
|
228
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_6.6.0_aarch64.dmg`
|
|
228
229
|
|
|
229
230
|
Do not upload `dist/*`. Package registry publishing remains owner-run.
|
|
230
231
|
|
|
@@ -243,6 +244,8 @@ Do not upload `dist/*`. Package registry publishing remains owner-run.
|
|
|
243
244
|
|
|
244
245
|
| Version | Theme |
|
|
245
246
|
| --- | --- |
|
|
247
|
+
| 6.6.0 | Brain Proof Runtime: backend-owned Brain proof API, model-continuity wiring, first-screen proof that saved context can be recalled across model changes, and direct Brain Home document upload |
|
|
248
|
+
| 6.5.0 | Brain Experience Readiness: Brain readiness signal, depth progress rail, source-aware memory-save feedback, and visual coverage for the first-memory loop |
|
|
246
249
|
| 6.4.0 | Digital Brain Quality Hardening: workspace-scoped graph/search/memory reads and mutations, Brain quality primitives, structured context guardrails, and retrieval benchmark coverage |
|
|
247
250
|
| 6.3.1 | Access Runtime / i18n Follow-up: app-factory access-control extraction, focused access runtime tests, and Capture/Review Center i18n coverage |
|
|
248
251
|
| 6.3.0 | Product Hardening Completion: Brain archive/provenance/ingestion UX polish, Review Center Run Now contract hardening, local model runtime status, app-factory review wiring, shim smoke, i18n guard, and exact release artifacts |
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,68 @@
|
|
|
3
3
|
The top entry is the current release-preparation target. Older entries are
|
|
4
4
|
historical and may describe behavior as it existed at that release.
|
|
5
5
|
|
|
6
|
+
## [6.6.0] - 2026-06-18
|
|
7
|
+
|
|
8
|
+
> Brain Proof Runtime. Makes the first-five-minute Brain value visible by
|
|
9
|
+
> showing backend-owned evidence that saved context can be recalled and survives
|
|
10
|
+
> model changes.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `/api/memory/brain-proof`, backed by `MemoryService.brain_proof()`, combining
|
|
14
|
+
Brain readiness, durable memory counts, graph/vector depth, active model id,
|
|
15
|
+
and a unified recall sample.
|
|
16
|
+
- Brain Home proof strip for recallable context, model-continuity, and
|
|
17
|
+
knowledge-store state.
|
|
18
|
+
- Recent recall proof card that surfaces the latest memory/item the Brain can
|
|
19
|
+
bring back after a useful exchange.
|
|
20
|
+
- Brain Home document upload CTA in the empty state and composer, giving the
|
|
21
|
+
first session a direct way to grow the Brain with files.
|
|
22
|
+
- Unit coverage for model-independent Brain proof recall behavior.
|
|
23
|
+
- Honest empty-state Brain proof: model-independent capability remains visible,
|
|
24
|
+
but continuity is only marked proven after durable evidence exists.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- Interaction router runtime context now carries an active-model getter into
|
|
28
|
+
the Memory router, reducing app-factory inline wiring while preserving route
|
|
29
|
+
order.
|
|
30
|
+
- Default Brain proof recall seeding is scoped to the current user/workspace
|
|
31
|
+
before falling back to conversation memory.
|
|
32
|
+
- Chat-to-Knowledge-Graph ingestion now carries workspace scope into projected
|
|
33
|
+
graph nodes, and Brain proof conversation counts use scoped conversations so
|
|
34
|
+
another user/workspace cannot make an empty Brain look proven.
|
|
35
|
+
- Direct Knowledge Graph ingest and document upload ingestion now resolve the
|
|
36
|
+
request workspace and project that scope into graph/source/document nodes.
|
|
37
|
+
- Package/runtime/static metadata is synchronized to 6.6.0; package publish and
|
|
38
|
+
deployment remain owner-run only.
|
|
39
|
+
|
|
40
|
+
## [6.5.0] - 2026-06-18
|
|
41
|
+
|
|
42
|
+
> Brain Experience Readiness. Uses the 6.4.0 quality baseline to improve what
|
|
43
|
+
> normal users can understand: how alive the Brain is, where they are in the
|
|
44
|
+
> memory-to-graph journey, and what changed after a useful exchange is saved.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- Brain Home readiness strip that classifies the current Brain as waiting for
|
|
48
|
+
its first memory, forming topics, or ready for map exploration.
|
|
49
|
+
- Backend-owned Brain readiness summary from `MemoryService`, exposed through
|
|
50
|
+
`/api/memory/manager` and `/api/memory/brain-quality`, so the UI no longer
|
|
51
|
+
has to infer Brain growth from local fragments.
|
|
52
|
+
- Persistent depth progress rail across the Living Brain surface so the
|
|
53
|
+
memory -> topics -> relationships -> graph journey is visible and reversible.
|
|
54
|
+
- Source-aware memory-save detail under chat feedback, making the recall loop
|
|
55
|
+
explicit after a conversation enriches the Brain.
|
|
56
|
+
- Visual regression assertions for Brain readiness, depth progress, and
|
|
57
|
+
source-aware memory-save feedback.
|
|
58
|
+
|
|
59
|
+
### Changed
|
|
60
|
+
- Brain overview empty states now guide first-memory use without exposing graph
|
|
61
|
+
internals or administrator language.
|
|
62
|
+
- Brain readiness now uses the same memory, graph, relationship, and source
|
|
63
|
+
health signals that the Memory Manager reports, keeping product UX aligned
|
|
64
|
+
with backend Brain state.
|
|
65
|
+
- Package/runtime/static metadata is synchronized to 6.5.0; package publish and
|
|
66
|
+
deployment remain owner-run only.
|
|
67
|
+
|
|
6
68
|
## [6.4.0] - 2026-06-17
|
|
7
69
|
|
|
8
70
|
> Digital Brain Quality Hardening. Tightens workspace-scoped Brain retrieval
|
package/frontend/openapi.json
CHANGED
|
@@ -3757,7 +3757,7 @@
|
|
|
3757
3757
|
},
|
|
3758
3758
|
"info": {
|
|
3759
3759
|
"title": "Lattice AI Server (local)",
|
|
3760
|
-
"version": "
|
|
3760
|
+
"version": "6.6.0"
|
|
3761
3761
|
},
|
|
3762
3762
|
"openapi": "3.1.0",
|
|
3763
3763
|
"paths": {
|
|
@@ -6941,6 +6941,70 @@
|
|
|
6941
6941
|
"summary": "Local Agent Status"
|
|
6942
6942
|
}
|
|
6943
6943
|
},
|
|
6944
|
+
"/api/memory/brain-proof": {
|
|
6945
|
+
"get": {
|
|
6946
|
+
"operationId": "brain_proof_api_memory_brain_proof_get",
|
|
6947
|
+
"parameters": [
|
|
6948
|
+
{
|
|
6949
|
+
"in": "query",
|
|
6950
|
+
"name": "q",
|
|
6951
|
+
"required": false,
|
|
6952
|
+
"schema": {
|
|
6953
|
+
"default": "",
|
|
6954
|
+
"title": "Q",
|
|
6955
|
+
"type": "string"
|
|
6956
|
+
}
|
|
6957
|
+
},
|
|
6958
|
+
{
|
|
6959
|
+
"in": "query",
|
|
6960
|
+
"name": "limit",
|
|
6961
|
+
"required": false,
|
|
6962
|
+
"schema": {
|
|
6963
|
+
"default": 3,
|
|
6964
|
+
"title": "Limit",
|
|
6965
|
+
"type": "integer"
|
|
6966
|
+
}
|
|
6967
|
+
}
|
|
6968
|
+
],
|
|
6969
|
+
"responses": {
|
|
6970
|
+
"200": {
|
|
6971
|
+
"content": {
|
|
6972
|
+
"application/json": {
|
|
6973
|
+
"schema": {}
|
|
6974
|
+
}
|
|
6975
|
+
},
|
|
6976
|
+
"description": "Successful Response"
|
|
6977
|
+
},
|
|
6978
|
+
"422": {
|
|
6979
|
+
"content": {
|
|
6980
|
+
"application/json": {
|
|
6981
|
+
"schema": {
|
|
6982
|
+
"$ref": "#/components/schemas/HTTPValidationError"
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
},
|
|
6986
|
+
"description": "Validation Error"
|
|
6987
|
+
}
|
|
6988
|
+
},
|
|
6989
|
+
"summary": "Brain Proof"
|
|
6990
|
+
}
|
|
6991
|
+
},
|
|
6992
|
+
"/api/memory/brain-quality": {
|
|
6993
|
+
"get": {
|
|
6994
|
+
"operationId": "brain_quality_summary_api_memory_brain_quality_get",
|
|
6995
|
+
"responses": {
|
|
6996
|
+
"200": {
|
|
6997
|
+
"content": {
|
|
6998
|
+
"application/json": {
|
|
6999
|
+
"schema": {}
|
|
7000
|
+
}
|
|
7001
|
+
},
|
|
7002
|
+
"description": "Successful Response"
|
|
7003
|
+
}
|
|
7004
|
+
},
|
|
7005
|
+
"summary": "Brain Quality Summary"
|
|
7006
|
+
}
|
|
7007
|
+
},
|
|
6944
7008
|
"/api/memory/clear": {
|
|
6945
7009
|
"post": {
|
|
6946
7010
|
"operationId": "memory_clear_api_memory_clear_post",
|
|
@@ -445,6 +445,8 @@ export const latticeApi = {
|
|
|
445
445
|
},
|
|
446
446
|
browserReadUrl: (url: string) => post("/api/browser/read-url", { url }, {}),
|
|
447
447
|
memoryManager: () => get("/api/memory/manager", { sources: [], tiers: [], usage: {} }),
|
|
448
|
+
memoryBrainQuality: () => get("/api/memory/brain-quality", {}),
|
|
449
|
+
memoryBrainProof: (query = "", limit = 3) => get("/api/memory/brain-proof", { proofs: {}, recall: { items: [] }, model_continuity: {}, claims: {} }, { q: query, limit }),
|
|
448
450
|
memoryRecall: (query: string, limit = 20) => post("/api/memory/recall", { query, limit }, { matches: [] }),
|
|
449
451
|
memoryCompact: () => post("/api/memory/compact", {}, {}),
|
|
450
452
|
memoryRebuild: () => post("/api/memory/rebuild", { target: "vector" }, {}),
|
|
@@ -1550,6 +1550,40 @@ export interface paths {
|
|
|
1550
1550
|
patch?: never;
|
|
1551
1551
|
trace?: never;
|
|
1552
1552
|
};
|
|
1553
|
+
"/api/memory/brain-proof": {
|
|
1554
|
+
parameters: {
|
|
1555
|
+
query?: never;
|
|
1556
|
+
header?: never;
|
|
1557
|
+
path?: never;
|
|
1558
|
+
cookie?: never;
|
|
1559
|
+
};
|
|
1560
|
+
/** Brain Proof */
|
|
1561
|
+
get: operations["brain_proof_api_memory_brain_proof_get"];
|
|
1562
|
+
put?: never;
|
|
1563
|
+
post?: never;
|
|
1564
|
+
delete?: never;
|
|
1565
|
+
options?: never;
|
|
1566
|
+
head?: never;
|
|
1567
|
+
patch?: never;
|
|
1568
|
+
trace?: never;
|
|
1569
|
+
};
|
|
1570
|
+
"/api/memory/brain-quality": {
|
|
1571
|
+
parameters: {
|
|
1572
|
+
query?: never;
|
|
1573
|
+
header?: never;
|
|
1574
|
+
path?: never;
|
|
1575
|
+
cookie?: never;
|
|
1576
|
+
};
|
|
1577
|
+
/** Brain Quality Summary */
|
|
1578
|
+
get: operations["brain_quality_summary_api_memory_brain_quality_get"];
|
|
1579
|
+
put?: never;
|
|
1580
|
+
post?: never;
|
|
1581
|
+
delete?: never;
|
|
1582
|
+
options?: never;
|
|
1583
|
+
head?: never;
|
|
1584
|
+
patch?: never;
|
|
1585
|
+
trace?: never;
|
|
1586
|
+
};
|
|
1553
1587
|
"/api/memory/clear": {
|
|
1554
1588
|
parameters: {
|
|
1555
1589
|
query?: never;
|
|
@@ -10322,6 +10356,58 @@ export interface operations {
|
|
|
10322
10356
|
};
|
|
10323
10357
|
};
|
|
10324
10358
|
};
|
|
10359
|
+
brain_proof_api_memory_brain_proof_get: {
|
|
10360
|
+
parameters: {
|
|
10361
|
+
query?: {
|
|
10362
|
+
q?: string;
|
|
10363
|
+
limit?: number;
|
|
10364
|
+
};
|
|
10365
|
+
header?: never;
|
|
10366
|
+
path?: never;
|
|
10367
|
+
cookie?: never;
|
|
10368
|
+
};
|
|
10369
|
+
requestBody?: never;
|
|
10370
|
+
responses: {
|
|
10371
|
+
/** @description Successful Response */
|
|
10372
|
+
200: {
|
|
10373
|
+
headers: {
|
|
10374
|
+
[name: string]: unknown;
|
|
10375
|
+
};
|
|
10376
|
+
content: {
|
|
10377
|
+
"application/json": unknown;
|
|
10378
|
+
};
|
|
10379
|
+
};
|
|
10380
|
+
/** @description Validation Error */
|
|
10381
|
+
422: {
|
|
10382
|
+
headers: {
|
|
10383
|
+
[name: string]: unknown;
|
|
10384
|
+
};
|
|
10385
|
+
content: {
|
|
10386
|
+
"application/json": components["schemas"]["HTTPValidationError"];
|
|
10387
|
+
};
|
|
10388
|
+
};
|
|
10389
|
+
};
|
|
10390
|
+
};
|
|
10391
|
+
brain_quality_summary_api_memory_brain_quality_get: {
|
|
10392
|
+
parameters: {
|
|
10393
|
+
query?: never;
|
|
10394
|
+
header?: never;
|
|
10395
|
+
path?: never;
|
|
10396
|
+
cookie?: never;
|
|
10397
|
+
};
|
|
10398
|
+
requestBody?: never;
|
|
10399
|
+
responses: {
|
|
10400
|
+
/** @description Successful Response */
|
|
10401
|
+
200: {
|
|
10402
|
+
headers: {
|
|
10403
|
+
[name: string]: unknown;
|
|
10404
|
+
};
|
|
10405
|
+
content: {
|
|
10406
|
+
"application/json": unknown;
|
|
10407
|
+
};
|
|
10408
|
+
};
|
|
10409
|
+
};
|
|
10410
|
+
};
|
|
10325
10411
|
memory_clear_api_memory_clear_post: {
|
|
10326
10412
|
parameters: {
|
|
10327
10413
|
query?: never;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { ImagePlus, Send } from "lucide-react";
|
|
2
|
+
import { FileUp, ImagePlus, Send } from "lucide-react";
|
|
3
3
|
import { Button } from "@/components/ui/button";
|
|
4
4
|
import { t, type Language } from "@/i18n";
|
|
5
5
|
|
|
@@ -8,16 +8,20 @@ export function BrainComposer({
|
|
|
8
8
|
draft,
|
|
9
9
|
streaming,
|
|
10
10
|
imageData,
|
|
11
|
+
uploadingDocument,
|
|
11
12
|
onDraftChange,
|
|
12
13
|
onImageDataChange,
|
|
14
|
+
onUploadDocument,
|
|
13
15
|
onSend,
|
|
14
16
|
}: {
|
|
15
17
|
language: Language;
|
|
16
18
|
draft: string;
|
|
17
19
|
streaming: boolean;
|
|
18
20
|
imageData: string | null;
|
|
21
|
+
uploadingDocument: boolean;
|
|
19
22
|
onDraftChange: (value: string) => void;
|
|
20
23
|
onImageDataChange: (value: string | null) => void;
|
|
24
|
+
onUploadDocument: (file: File) => void;
|
|
21
25
|
onSend: () => void;
|
|
22
26
|
}) {
|
|
23
27
|
return (
|
|
@@ -34,6 +38,21 @@ export function BrainComposer({
|
|
|
34
38
|
placeholder={t(language, "brain.placeholder")}
|
|
35
39
|
/>
|
|
36
40
|
<div className="brain-composer-actions">
|
|
41
|
+
<label className={`brain-document-input ${uploadingDocument ? "is-disabled" : ""}`}>
|
|
42
|
+
<FileUp className="h-3.5 w-3.5" />
|
|
43
|
+
<span>{uploadingDocument ? t(language, "brain.upload.uploading") : t(language, "brain.upload.ctaShort")}</span>
|
|
44
|
+
<input
|
|
45
|
+
type="file"
|
|
46
|
+
accept=".pdf,.docx,.xlsx,.pptx,.txt,.md,.csv,application/pdf,text/plain,text/markdown,text/csv"
|
|
47
|
+
className="sr-only"
|
|
48
|
+
disabled={uploadingDocument}
|
|
49
|
+
onChange={(event) => {
|
|
50
|
+
const file = event.target.files?.[0];
|
|
51
|
+
event.currentTarget.value = "";
|
|
52
|
+
if (file) onUploadDocument(file);
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
55
|
+
</label>
|
|
37
56
|
<label className="brain-image-input">
|
|
38
57
|
<ImagePlus className="h-3.5 w-3.5" />
|
|
39
58
|
<span>{t(language, "brain.image")}</span>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { ShieldCheck } from "lucide-react";
|
|
2
|
+
import { DatabaseZap, ShieldCheck } from "lucide-react";
|
|
3
3
|
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
|
|
4
4
|
import { t, type Language } from "@/i18n";
|
|
5
|
-
import type { BrainDepth, KnowledgeConcept, MemoryFragment, Message } from "./types";
|
|
5
|
+
import type { BrainDepth, BrainProof, BrainReadiness, KnowledgeConcept, MemoryFragment, Message } from "./types";
|
|
6
6
|
import { BrainCarePanel } from "./BrainCarePanel";
|
|
7
7
|
import { BrainComposer } from "./BrainComposer";
|
|
8
8
|
import { BrainOverviewPanel } from "./BrainOverviewPanel";
|
|
@@ -20,9 +20,13 @@ export function BrainConversation({
|
|
|
20
20
|
streamRef,
|
|
21
21
|
memories,
|
|
22
22
|
concepts,
|
|
23
|
+
readiness,
|
|
24
|
+
proof,
|
|
25
|
+
uploadingDocument,
|
|
23
26
|
onOpenDepth,
|
|
24
27
|
onDraftChange,
|
|
25
28
|
onImageDataChange,
|
|
29
|
+
onUploadDocument,
|
|
26
30
|
onSend,
|
|
27
31
|
}: {
|
|
28
32
|
language: Language;
|
|
@@ -37,9 +41,13 @@ export function BrainConversation({
|
|
|
37
41
|
streamRef: React.RefObject<HTMLDivElement | null>;
|
|
38
42
|
memories: MemoryFragment[];
|
|
39
43
|
concepts: KnowledgeConcept[];
|
|
44
|
+
readiness: BrainReadiness;
|
|
45
|
+
proof: BrainProof;
|
|
46
|
+
uploadingDocument: boolean;
|
|
40
47
|
onOpenDepth: (depth: BrainDepth) => void;
|
|
41
48
|
onDraftChange: (value: string) => void;
|
|
42
49
|
onImageDataChange: (value: string | null) => void;
|
|
50
|
+
onUploadDocument: (file: File) => void;
|
|
43
51
|
onSend: () => void;
|
|
44
52
|
}) {
|
|
45
53
|
return (
|
|
@@ -66,10 +74,18 @@ export function BrainConversation({
|
|
|
66
74
|
<BrainOverviewPanel
|
|
67
75
|
memories={memories}
|
|
68
76
|
concepts={concepts}
|
|
77
|
+
readiness={readiness}
|
|
78
|
+
proof={proof}
|
|
69
79
|
onOpenDepth={onOpenDepth}
|
|
70
80
|
/>
|
|
71
81
|
{messages.length === 0 ? (
|
|
72
|
-
<BrainEmptyState
|
|
82
|
+
<BrainEmptyState
|
|
83
|
+
language={language}
|
|
84
|
+
starterPrompts={starterPrompts}
|
|
85
|
+
uploadingDocument={uploadingDocument}
|
|
86
|
+
onDraftChange={onDraftChange}
|
|
87
|
+
onUploadDocument={onUploadDocument}
|
|
88
|
+
/>
|
|
73
89
|
) : (
|
|
74
90
|
messages.map((message, index) => (
|
|
75
91
|
<div key={`${message.role}-${index}`} className={`brain-message ${message.role}`}>
|
|
@@ -79,7 +95,13 @@ export function BrainConversation({
|
|
|
79
95
|
)}
|
|
80
96
|
</div>
|
|
81
97
|
|
|
82
|
-
{memoryFeedback ?
|
|
98
|
+
{memoryFeedback ? (
|
|
99
|
+
<div className="brain-save-feedback" role="status">
|
|
100
|
+
<DatabaseZap className="h-3.5 w-3.5" />
|
|
101
|
+
<span>{memoryFeedback}</span>
|
|
102
|
+
<small>{t(language, "brain.saved.detail")}</small>
|
|
103
|
+
</div>
|
|
104
|
+
) : null}
|
|
83
105
|
|
|
84
106
|
<BrainCarePanel language={language} />
|
|
85
107
|
|
|
@@ -88,8 +110,10 @@ export function BrainConversation({
|
|
|
88
110
|
draft={draft}
|
|
89
111
|
streaming={streaming}
|
|
90
112
|
imageData={imageData}
|
|
113
|
+
uploadingDocument={uploadingDocument}
|
|
91
114
|
onDraftChange={onDraftChange}
|
|
92
115
|
onImageDataChange={onImageDataChange}
|
|
116
|
+
onUploadDocument={onUploadDocument}
|
|
93
117
|
onSend={onSend}
|
|
94
118
|
/>
|
|
95
119
|
</section>
|
|
@@ -99,17 +123,37 @@ export function BrainConversation({
|
|
|
99
123
|
function BrainEmptyState({
|
|
100
124
|
language,
|
|
101
125
|
starterPrompts,
|
|
126
|
+
uploadingDocument,
|
|
102
127
|
onDraftChange,
|
|
128
|
+
onUploadDocument,
|
|
103
129
|
}: {
|
|
104
130
|
language: Language;
|
|
105
131
|
starterPrompts: string[];
|
|
132
|
+
uploadingDocument: boolean;
|
|
106
133
|
onDraftChange: (value: string) => void;
|
|
134
|
+
onUploadDocument: (file: File) => void;
|
|
107
135
|
}) {
|
|
108
136
|
return (
|
|
109
137
|
<div className="mind-empty">
|
|
110
138
|
<div className="mind-empty-kicker">{t(language, "brain.empty.kicker")}</div>
|
|
111
139
|
<div className="mind-empty-title">{t(language, "brain.empty.title")}</div>
|
|
112
140
|
<p>{t(language, "brain.empty.body")}</p>
|
|
141
|
+
<label className={`mind-empty-upload ${uploadingDocument ? "is-disabled" : ""}`}>
|
|
142
|
+
<DatabaseZap className="h-3.5 w-3.5" />
|
|
143
|
+
<span>{uploadingDocument ? t(language, "brain.upload.uploading") : t(language, "brain.upload.cta")}</span>
|
|
144
|
+
<input
|
|
145
|
+
type="file"
|
|
146
|
+
accept=".pdf,.docx,.xlsx,.pptx,.txt,.md,.csv,application/pdf,text/plain,text/markdown,text/csv"
|
|
147
|
+
className="sr-only"
|
|
148
|
+
disabled={uploadingDocument}
|
|
149
|
+
onChange={(event) => {
|
|
150
|
+
const file = event.target.files?.[0];
|
|
151
|
+
event.currentTarget.value = "";
|
|
152
|
+
if (file) onUploadDocument(file);
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
</label>
|
|
156
|
+
<small className="mind-empty-upload-hint">{t(language, "brain.upload.hint")}</small>
|
|
113
157
|
<div className="mind-empty-prompts" aria-label={t(language, "brain.aria.starterPrompts")}>
|
|
114
158
|
{starterPrompts.map((prompt) => (
|
|
115
159
|
<button key={prompt} type="button" onClick={() => onDraftChange(prompt)}>
|