ltcai 6.7.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -31
- package/docs/CHANGELOG.md +48 -0
- package/frontend/src/App.tsx +80 -0
- package/frontend/src/api/client.ts +11 -0
- package/frontend/src/components/AdminAccessGate.tsx +70 -0
- package/frontend/src/components/BrainConversation.tsx +232 -8
- package/frontend/src/components/FeedbackState.tsx +45 -0
- package/frontend/src/components/WorkspaceProfileSwitcher.tsx +176 -0
- package/frontend/src/components/onboarding/AnalysisScreen.tsx +20 -12
- package/frontend/src/components/onboarding/InstallScreen.tsx +55 -0
- package/frontend/src/components/onboarding/RecommendationScreen.tsx +55 -5
- package/frontend/src/components/onboarding/recommendationModel.ts +59 -2
- package/frontend/src/features/brain/BrainConversation.tsx +382 -7
- package/frontend/src/features/brain/BrainGraphLayer.tsx +258 -25
- package/frontend/src/features/brain/BrainHome.tsx +300 -1
- package/frontend/src/features/brain/brainData.ts +25 -1
- package/frontend/src/features/brain/graphLayout.ts +12 -1
- package/frontend/src/features/brain/types.ts +54 -0
- package/frontend/src/i18n.ts +374 -0
- package/frontend/src/store/appStore.ts +15 -0
- package/frontend/src/styles.css +1383 -41
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/workspace.py +59 -0
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/package.json +1 -1
- package/scripts/brain_quality_eval.py +118 -0
- 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 +28 -28
- package/static/app/assets/Act-BHEb8bAM.js +2 -0
- package/static/app/assets/{Act-DGN37eR4.js.map → Act-BHEb8bAM.js.map} +1 -1
- package/static/app/assets/Brain-yvR7xkrV.js +322 -0
- package/static/app/assets/Brain-yvR7xkrV.js.map +1 -0
- package/static/app/assets/Capture-BrAmsSEH.js +2 -0
- package/static/app/assets/Capture-BrAmsSEH.js.map +1 -0
- package/static/app/assets/Library-BOVzYfxI.js +2 -0
- package/static/app/assets/{Library-BbagRFyd.js.map → Library-BOVzYfxI.js.map} +1 -1
- package/static/app/assets/System-D4WaN4kj.js +2 -0
- package/static/app/assets/System-D4WaN4kj.js.map +1 -0
- package/static/app/assets/index-BOB-W1FZ.js +17 -0
- package/static/app/assets/index-BOB-W1FZ.js.map +1 -0
- package/static/app/assets/index-DvLsGy-z.css +2 -0
- package/static/app/assets/primitives-C3_BfUb8.js +2 -0
- package/static/app/assets/primitives-C3_BfUb8.js.map +1 -0
- package/static/app/assets/textarea-CbvhHvzg.js +2 -0
- package/static/app/assets/{textarea-C2PLu6_O.js.map → textarea-CbvhHvzg.js.map} +1 -1
- package/static/app/index.html +2 -2
- package/static/app/assets/Act-DGN37eR4.js +0 -2
- package/static/app/assets/Brain-HDcIwPHW.js +0 -322
- package/static/app/assets/Brain-HDcIwPHW.js.map +0 -1
- package/static/app/assets/Capture--eZfb_Ex.js +0 -2
- package/static/app/assets/Capture--eZfb_Ex.js.map +0 -1
- package/static/app/assets/Library-BbagRFyd.js +0 -2
- package/static/app/assets/System-C6pd3Mp_.js +0 -2
- package/static/app/assets/System-C6pd3Mp_.js.map +0 -1
- package/static/app/assets/index-C950aES_.js +0 -17
- package/static/app/assets/index-C950aES_.js.map +0 -1
- package/static/app/assets/index-ztppMg0c.css +0 -2
- package/static/app/assets/primitives-Bcm5lZRu.js +0 -2
- package/static/app/assets/primitives-Bcm5lZRu.js.map +0 -1
- package/static/app/assets/textarea-C2PLu6_O.js +0 -2
package/frontend/src/i18n.ts
CHANGED
|
@@ -43,6 +43,28 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
43
43
|
"brain.portable": "이동 가능",
|
|
44
44
|
"brain.private": "개인 소유",
|
|
45
45
|
"brain.admin": "관리자 콘솔",
|
|
46
|
+
"shell.workspace.label": "작업공간 및 프로필",
|
|
47
|
+
"shell.workspace.current": "현재 작업공간",
|
|
48
|
+
"shell.workspace.switch": "전환",
|
|
49
|
+
"shell.workspace.active": "사용 중",
|
|
50
|
+
"shell.workspace.empty": "아직 작업공간이 없습니다",
|
|
51
|
+
"shell.workspace.personal": "개인 Brain",
|
|
52
|
+
"shell.workspace.manageSpaces": "작업공간 관리",
|
|
53
|
+
"shell.workspace.close": "닫기",
|
|
54
|
+
"shell.profile.label": "프로필",
|
|
55
|
+
"shell.profile.owner": "소유자",
|
|
56
|
+
"shell.profile.signedOut": "로그인하지 않음",
|
|
57
|
+
"shell.profile.manage": "계정 설정 열기",
|
|
58
|
+
"shell.admin.label": "관리자",
|
|
59
|
+
"shell.admin.open": "관리자 콘솔 열기",
|
|
60
|
+
"shell.admin.tooltip": "설정, 에이전트, 도구 레지스트리 관리",
|
|
61
|
+
"shell.admin.needsMode": "관리자 콘솔은 고급 또는 관리자 모드에서만 사용할 수 있습니다",
|
|
62
|
+
"shell.admin.enable": "관리자 모드로 전환",
|
|
63
|
+
"shell.mode.label": "모드",
|
|
64
|
+
"shell.mode.basic": "기본",
|
|
65
|
+
"shell.mode.advanced": "고급",
|
|
66
|
+
"shell.mode.admin": "관리자",
|
|
67
|
+
"shell.mode.info": "모드는 표시되는 도구와 관리자 화면의 범위를 정합니다",
|
|
46
68
|
"brain.action.add": "넣기",
|
|
47
69
|
"brain.action.find": "찾기",
|
|
48
70
|
"brain.action.model": "모델",
|
|
@@ -65,6 +87,58 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
65
87
|
"brain.upload.pending": "{name}을 Brain에 넣는 중입니다.",
|
|
66
88
|
"brain.upload.saved": "{name}이 Brain에 저장됐습니다.",
|
|
67
89
|
"brain.upload.failed": "문서를 넣지 못했습니다: {reason}",
|
|
90
|
+
"brain.ingest.aria": "Brain에 넣기",
|
|
91
|
+
"brain.ingest.kicker": "5분 안에 Brain 만들기",
|
|
92
|
+
"brain.ingest.title": "파일, 폴더, 노트, 웹을 바로 넣으세요.",
|
|
93
|
+
"brain.ingest.file": "파일 넣기",
|
|
94
|
+
"brain.ingest.file.detail": "PDF, 문서, 표, 메모",
|
|
95
|
+
"brain.ingest.folder": "폴더 넣기",
|
|
96
|
+
"brain.ingest.folder.placeholder": "로컬 폴더 경로",
|
|
97
|
+
"brain.ingest.note": "노트 넣기",
|
|
98
|
+
"brain.ingest.note.placeholder": "결정이나 맥락을 붙여넣기",
|
|
99
|
+
"brain.ingest.web": "웹 넣기",
|
|
100
|
+
"brain.ingest.web.placeholder": "https://...",
|
|
101
|
+
"brain.ingest.folder.pending": "{path} 폴더를 Brain에 연결 중입니다.",
|
|
102
|
+
"brain.ingest.folder.saved": "{path} 폴더가 Brain에 연결됐습니다.",
|
|
103
|
+
"brain.ingest.folder.failed": "폴더를 넣지 못했습니다: {reason}",
|
|
104
|
+
"brain.ingest.note.pending": "노트를 Brain에 저장 중입니다.",
|
|
105
|
+
"brain.ingest.note.saved": "노트가 Brain에 저장됐습니다.",
|
|
106
|
+
"brain.ingest.note.failed": "노트를 넣지 못했습니다: {reason}",
|
|
107
|
+
"brain.ingest.web.pending": "{url}을 읽어 Brain에 넣는 중입니다.",
|
|
108
|
+
"brain.ingest.web.saved": "{url}이 Brain에 저장됐습니다.",
|
|
109
|
+
"brain.ingest.web.failed": "웹 페이지를 넣지 못했습니다: {reason}",
|
|
110
|
+
"brain.ingest.type.file": "파일",
|
|
111
|
+
"brain.ingest.type.folder": "폴더",
|
|
112
|
+
"brain.ingest.type.note": "노트",
|
|
113
|
+
"brain.ingest.type.web": "웹",
|
|
114
|
+
"brain.ingest.cta.file": "선택해서 바로 넣기",
|
|
115
|
+
"brain.ingest.cta.folder": "경로를 넣고 Enter",
|
|
116
|
+
"brain.ingest.cta.note": "내용을 붙여넣고 Enter",
|
|
117
|
+
"brain.ingest.cta.web": "URL을 넣고 Enter",
|
|
118
|
+
"brain.ingest.active": "{label} 처리 중",
|
|
119
|
+
"brain.ingest.progress.aria": "{label} 수집 진행 상태",
|
|
120
|
+
"brain.ingest.stage.preparing": "준비",
|
|
121
|
+
"brain.ingest.stage.parsing": "파싱",
|
|
122
|
+
"brain.ingest.stage.embedding": "임베딩",
|
|
123
|
+
"brain.ingest.stage.indexing": "인덱싱",
|
|
124
|
+
"brain.ingest.stage.complete": "메모리화 완료",
|
|
125
|
+
"brain.ingest.stage.error": "실패",
|
|
126
|
+
"brain.ingest.stage.preparing.hint": "원본을 읽어들이는 중",
|
|
127
|
+
"brain.ingest.stage.parsing.hint": "텍스트와 구조를 추출하는 중",
|
|
128
|
+
"brain.ingest.stage.embedding.hint": "의미 벡터로 변환하는 중",
|
|
129
|
+
"brain.ingest.stage.indexing.hint": "지식 그래프에 연결하는 중",
|
|
130
|
+
"brain.ingest.stage.complete.hint": "내 지식으로 들어왔습니다",
|
|
131
|
+
"brain.ingest.result": "새 기억 {memories}개 · 새 엔티티 {entities}개",
|
|
132
|
+
"brain.ingest.result.empty": "기존 지식과 통합됨",
|
|
133
|
+
"brain.timeline.aria": "최근 메모리 생성 타임라인",
|
|
134
|
+
"brain.timeline.emergenceTitle": "방금 생긴 지식",
|
|
135
|
+
"brain.timeline.recent": "최근 수집",
|
|
136
|
+
"brain.timeline.newMemories": "새 기억 {count}개",
|
|
137
|
+
"brain.timeline.newEntities": "새 엔티티 {count}개",
|
|
138
|
+
"brain.timeline.at": "{time}",
|
|
139
|
+
"brain.timeline.justNow": "방금",
|
|
140
|
+
"brain.timeline.minutesAgo": "{count}분 전",
|
|
141
|
+
"brain.timeline.empty": "아직 수집 기록이 없습니다. 위에서 무엇이든 넣어보세요.",
|
|
68
142
|
"brain.image": "이미지",
|
|
69
143
|
"brain.unavailable": "지금은 답할 수 없음",
|
|
70
144
|
"brain.imageAttached": "이미지 첨부됨",
|
|
@@ -104,6 +178,33 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
104
178
|
"brain.proof.recallEmpty.detail": "아직 저장된 기억이 없어서 가짜 예시는 보여주지 않습니다.",
|
|
105
179
|
"brain.proof.recallPending": "기억은 저장됐고 recall 증거를 준비 중입니다.",
|
|
106
180
|
"brain.proof.recallPending.detail": "인덱싱이 끝나면 이 자리에서 실제 기억을 다시 보여줍니다.",
|
|
181
|
+
"brain.modelDemo.aria": "모델 교체 증거",
|
|
182
|
+
"brain.modelDemo.kicker": "모델 독립 Brain",
|
|
183
|
+
"brain.modelDemo.proven": "현재 기억은 모델 밖에 남아 있습니다.",
|
|
184
|
+
"brain.modelDemo.pending": "첫 기억이 저장되면 모델 교체 증거가 생깁니다.",
|
|
185
|
+
"brain.modelDemo.detail": "현재 모델: {model}. 같은 질문으로 Brain 증거를 다시 확인할 수 있습니다.",
|
|
186
|
+
"brain.modelDemo.verify": "같은 증거 확인",
|
|
187
|
+
"brain.modelDemo.change": "모델 바꾸기",
|
|
188
|
+
"brain.modelDemo.needQuestion": "먼저 질문하거나 기억을 넣으면 같은 증거를 다시 확인할 수 있습니다.",
|
|
189
|
+
"brain.modelDemo.checking": "{model}에서 같은 Brain 증거를 다시 확인 중입니다.",
|
|
190
|
+
"brain.modelDemo.done": "{model}에서도 같은 Brain 증거를 확인했습니다.",
|
|
191
|
+
"brain.answerProof.aria": "답변 출처와 Memory proof",
|
|
192
|
+
"brain.answerProof.title": "Memory proof + source citation",
|
|
193
|
+
"brain.answerProof.modelProven": "{model} 밖에 남은 Brain 증거",
|
|
194
|
+
"brain.answerProof.modelPending": "{model} 응답 · 증거 저장 대기",
|
|
195
|
+
"brain.answerProof.empty": "아직 연결된 출처가 없습니다. 기억이 인덱싱되면 여기에 표시됩니다.",
|
|
196
|
+
"brain.citation.chip": "출처 {num}",
|
|
197
|
+
"brain.citation.chip.long": "출처 {num}: {title}",
|
|
198
|
+
"brain.citation.expand": "출처 열기",
|
|
199
|
+
"brain.citation.close": "출처 닫기",
|
|
200
|
+
"brain.citation.preview.from": "출처: ",
|
|
201
|
+
"brain.citation.preview.snippet": "발췌: ",
|
|
202
|
+
"brain.citation.keyboard.tip": "스페이스/엔터로 출처를 열고, ESC로 닫습니다.",
|
|
203
|
+
"brain.citation.region": "본문에서 참조한 출처 인용",
|
|
204
|
+
"brain.citation.announce.open": "{num}번 출처를 열었습니다: {title}",
|
|
205
|
+
"brain.citation.announce.close": "출처 미리보기를 닫았습니다.",
|
|
206
|
+
"brain.citation.count": "이 답변은 {count}개의 출처를 인용합니다.",
|
|
207
|
+
"brain.citation.score": "관련도 {score}%",
|
|
107
208
|
"brain.memory.empty.kicker": "첫 기억",
|
|
108
209
|
"brain.memory.empty": "기억이 조용합니다.",
|
|
109
210
|
"brain.knowledge.empty": "지식이 형성되는 중입니다.",
|
|
@@ -113,6 +214,24 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
113
214
|
"brain.graph.emptyFocus": "대화, 문서, 프로젝트를 쌓으면 Brain 그래프가 자랍니다.",
|
|
114
215
|
"brain.graph.search": "검색",
|
|
115
216
|
"brain.graph.searchAria": "지식 그래프 검색",
|
|
217
|
+
"brain.graph.control.panel": "그래프 탐색 컨트롤",
|
|
218
|
+
"brain.graph.control.filter": "필터",
|
|
219
|
+
"brain.graph.control.types": "엔티티 타입",
|
|
220
|
+
"brain.graph.control.allTypes": "전체 타입",
|
|
221
|
+
"brain.graph.control.time": "시간 탐색",
|
|
222
|
+
"brain.graph.control.dateRange": "최근 추가 강조 범위",
|
|
223
|
+
"brain.graph.control.resetFilters": "필터 초기화",
|
|
224
|
+
"brain.graph.control.recentWindow": "최근 {days}일",
|
|
225
|
+
"brain.graph.control.allTime": "전체 기간",
|
|
226
|
+
"brain.graph.control.toggleType": "{type} 타입 표시 전환",
|
|
227
|
+
"brain.graph.search.typeahead": "검색 추천",
|
|
228
|
+
"brain.graph.search.typeaheadAria": "검색 추천 결과",
|
|
229
|
+
"brain.graph.search.noMatches": "일치하는 노드가 없습니다.",
|
|
230
|
+
"brain.graph.search.matchCount": "{count}개 일치",
|
|
231
|
+
"brain.graph.focus.neighbors": "이웃 {count}개 강조",
|
|
232
|
+
"brain.graph.focus.smooth": "선택한 노드로 부드럽게 포커스 이동하고 이웃을 강조합니다.",
|
|
233
|
+
"brain.graph.focus.recent": "최근 추가됨",
|
|
234
|
+
"brain.graph.focus.clear": "포커스 해제",
|
|
116
235
|
"care.title": "내 Brain 돌보기",
|
|
117
236
|
"care.subtitle": "내 컴퓨터에 두고, 필요하면 옮길 수 있습니다.",
|
|
118
237
|
"care.private": "개인 보관",
|
|
@@ -300,6 +419,37 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
300
419
|
"flow.install.step.download": "다운로드",
|
|
301
420
|
"flow.install.step.validate": "확인",
|
|
302
421
|
"flow.install.step.load": "로드",
|
|
422
|
+
"flow.analysis.hardware.icon.chip": "🖥️",
|
|
423
|
+
"flow.analysis.hardware.icon.ram": "🧠",
|
|
424
|
+
"flow.analysis.hardware.icon.gpu": "⚡",
|
|
425
|
+
"flow.analysis.hardware.icon.support": "🧩",
|
|
426
|
+
"flow.analysis.hardware.icon.models": "📦",
|
|
427
|
+
"flow.analysis.hardware.label.chip": "컴퓨터 (운영체제와 칩)",
|
|
428
|
+
"flow.analysis.hardware.label.ram": "메모리 (생각할 작업 공간, RAM)",
|
|
429
|
+
"flow.analysis.hardware.label.gpu": "그래픽 (계산을 도와주는 GPU)",
|
|
430
|
+
"flow.analysis.hardware.label.support": "로컬 지원 (모델 실행 도우미)",
|
|
431
|
+
"flow.analysis.hardware.label.models": "모델 (설치된 AI Brain)",
|
|
432
|
+
"flow.recommend.timeEstimate": "다운로드 약 {download} · 첫 응답 약 {response}초",
|
|
433
|
+
"flow.recommend.timeEstimate.ready": "다운로드 불필요 · 첫 응답 약 {response}초",
|
|
434
|
+
"flow.recommend.timeEstimate.unknown": "다운로드 시간 미확인 · 첫 응답 약 {response}초",
|
|
435
|
+
"flow.recommend.timeNote": "네트워크 속도에 따라 달라질 수 있어요.",
|
|
436
|
+
"flow.recommend.minutes": "{count}분",
|
|
437
|
+
"flow.recommend.comparison.faster": "(더 빠름)",
|
|
438
|
+
"flow.recommend.comparison.advanced": "(더 강력함)",
|
|
439
|
+
"flow.recommend.choose": "이 모델 선택",
|
|
440
|
+
"flow.recommend.primaryNote": "약 {time} 후 사용 준비 완료",
|
|
441
|
+
"flow.recommend.primaryNote.unknown": "다운로드 후 바로 사용 준비 완료",
|
|
442
|
+
"flow.recommend.nextHint": "선택하면 다운로드와 준비 화면으로 넘어가고, 끝나면 바로 Brain이 열립니다.",
|
|
443
|
+
"flow.install.expectedTitle": "예상 진행",
|
|
444
|
+
"flow.install.expected": "약 {download} 다운로드 후 약 {response}초 안에 첫 응답",
|
|
445
|
+
"flow.install.expected.ready": "다운로드 없이 약 {response}초 안에 첫 응답",
|
|
446
|
+
"flow.install.expected.unknown": "다운로드 후 약 {response}초 안에 첫 응답",
|
|
447
|
+
"flow.install.timelineStep.download": "모델 다운로드",
|
|
448
|
+
"flow.install.timelineStep.validate": "응답 확인",
|
|
449
|
+
"flow.install.timelineStep.load": "Brain에 로드",
|
|
450
|
+
"flow.install.timelineApprox": "약 {time}",
|
|
451
|
+
"flow.install.timelineQuick": "잠깐",
|
|
452
|
+
"flow.install.expectedCompletion": "끝나면 바로 Brain이 열립니다.",
|
|
303
453
|
"flow.shell": "내 로컬 AI 브레인 만들기",
|
|
304
454
|
"flow.login.title": "내 AI 브레인의 주인을 정합니다.",
|
|
305
455
|
"flow.login.body": "Lattice AI는 내 지식과 맥락을 이 컴퓨터에 보관하는 로컬 우선 AI 브레인입니다. 모델은 바꿀 수 있고, 외부 전송은 사용자가 선택할 때만 시작됩니다.",
|
|
@@ -366,6 +516,43 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
366
516
|
"flow.consent.location": "저장 위치",
|
|
367
517
|
"flow.consent.external": "외부 접속 대상",
|
|
368
518
|
"flow.consent.externalNone": "선택 전 외부 접속 없음",
|
|
519
|
+
"brain.answerProof.citationsLabel": "근거 출처 {count}개",
|
|
520
|
+
"brain.answerProof.marker": "출처 {index}로 이동",
|
|
521
|
+
"brain.answerProof.markerShort": "출처 {index}",
|
|
522
|
+
"brain.answerProof.citationItem": "출처 {index}: {title}",
|
|
523
|
+
"brain.answerProof.modelLine": "{model} 기준 답변 근거",
|
|
524
|
+
"shell.account.aria": "계정과 워크스페이스",
|
|
525
|
+
"shell.account.workspaceLabel": "워크스페이스",
|
|
526
|
+
"shell.account.personal": "개인 Brain",
|
|
527
|
+
"shell.account.modeLabel": "보기 모드",
|
|
528
|
+
"shell.account.mode.basic": "기본",
|
|
529
|
+
"shell.account.mode.advanced": "고급",
|
|
530
|
+
"shell.account.mode.admin": "관리자",
|
|
531
|
+
"shell.account.open": "계정·워크스페이스 메뉴 열기",
|
|
532
|
+
"shell.account.menuAria": "계정과 워크스페이스 메뉴",
|
|
533
|
+
"shell.account.profile": "프로필과 계정",
|
|
534
|
+
"shell.account.workspaces": "워크스페이스 전환",
|
|
535
|
+
"shell.account.admin": "관리자 콘솔",
|
|
536
|
+
"shell.account.settings": "설정 열기",
|
|
537
|
+
"shell.sync.aria": "VS Code 확장 연동 상태",
|
|
538
|
+
"shell.sync.label": "VS Code",
|
|
539
|
+
"shell.sync.connected": "연결됨",
|
|
540
|
+
"shell.sync.indexing": "인덱싱 중",
|
|
541
|
+
"shell.sync.synced": "동기화됨",
|
|
542
|
+
"shell.sync.offline": "연결 안 됨",
|
|
543
|
+
"shell.sync.checking": "확인 중",
|
|
544
|
+
"shell.sync.detail": "확장과 메인 앱이 같은 Brain을 공유합니다.",
|
|
545
|
+
"shell.sync.detailOffline": "VS Code 확장이 아직 이 Brain에 연결되지 않았습니다.",
|
|
546
|
+
"feedback.retry": "다시 시도",
|
|
547
|
+
"feedback.error.title": "문제가 생겼어요",
|
|
548
|
+
"feedback.error.body": "잠시 후 다시 시도하거나 설정에서 연결을 확인하세요.",
|
|
549
|
+
"feedback.consent.aria": "외부 연결 동의 상태",
|
|
550
|
+
"feedback.consent.activeTitle": "외부 연결 허용됨",
|
|
551
|
+
"feedback.consent.activeBody": "필요할 때만 외부 저장소에서 모델과 페이지를 가져옵니다.",
|
|
552
|
+
"feedback.consent.revoke": "외부 연결 해제",
|
|
553
|
+
"feedback.consent.revokedTitle": "외부 연결이 해제되었습니다",
|
|
554
|
+
"feedback.consent.revokedBody": "이 Brain은 지금 완전히 로컬에서만 동작합니다. 다시 허용하려면 아래에서 켜세요.",
|
|
555
|
+
"feedback.consent.reenable": "다시 허용",
|
|
369
556
|
},
|
|
370
557
|
en: {
|
|
371
558
|
"language.label": "Language",
|
|
@@ -402,6 +589,28 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
402
589
|
"brain.portable": "Portable",
|
|
403
590
|
"brain.private": "Private",
|
|
404
591
|
"brain.admin": "Admin Console",
|
|
592
|
+
"shell.workspace.label": "Workspace and profile",
|
|
593
|
+
"shell.workspace.current": "Current workspace",
|
|
594
|
+
"shell.workspace.switch": "Switch",
|
|
595
|
+
"shell.workspace.active": "Active",
|
|
596
|
+
"shell.workspace.empty": "No workspaces yet",
|
|
597
|
+
"shell.workspace.personal": "Personal Brain",
|
|
598
|
+
"shell.workspace.manageSpaces": "Manage workspaces",
|
|
599
|
+
"shell.workspace.close": "Close",
|
|
600
|
+
"shell.profile.label": "Profile",
|
|
601
|
+
"shell.profile.owner": "Owner",
|
|
602
|
+
"shell.profile.signedOut": "Not signed in",
|
|
603
|
+
"shell.profile.manage": "Open account settings",
|
|
604
|
+
"shell.admin.label": "Admin",
|
|
605
|
+
"shell.admin.open": "Open Admin Console",
|
|
606
|
+
"shell.admin.tooltip": "Manage settings, agents, and the tool registry",
|
|
607
|
+
"shell.admin.needsMode": "Admin Console is available in Advanced or Admin mode",
|
|
608
|
+
"shell.admin.enable": "Switch to Admin mode",
|
|
609
|
+
"shell.mode.label": "Mode",
|
|
610
|
+
"shell.mode.basic": "Basic",
|
|
611
|
+
"shell.mode.advanced": "Advanced",
|
|
612
|
+
"shell.mode.admin": "Admin",
|
|
613
|
+
"shell.mode.info": "Mode sets which tools and admin surfaces are shown",
|
|
405
614
|
"brain.action.add": "Add",
|
|
406
615
|
"brain.action.find": "Find",
|
|
407
616
|
"brain.action.model": "Model",
|
|
@@ -424,6 +633,58 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
424
633
|
"brain.upload.pending": "Adding {name} to Brain.",
|
|
425
634
|
"brain.upload.saved": "{name} was saved to Brain.",
|
|
426
635
|
"brain.upload.failed": "Could not add the document: {reason}",
|
|
636
|
+
"brain.ingest.aria": "Add to Brain",
|
|
637
|
+
"brain.ingest.kicker": "Build a Brain in 5 minutes",
|
|
638
|
+
"brain.ingest.title": "Add files, folders, notes, and web pages immediately.",
|
|
639
|
+
"brain.ingest.file": "Add file",
|
|
640
|
+
"brain.ingest.file.detail": "PDFs, docs, tables, notes",
|
|
641
|
+
"brain.ingest.folder": "Add folder",
|
|
642
|
+
"brain.ingest.folder.placeholder": "Local folder path",
|
|
643
|
+
"brain.ingest.note": "Add note",
|
|
644
|
+
"brain.ingest.note.placeholder": "Paste a decision or context",
|
|
645
|
+
"brain.ingest.web": "Add web",
|
|
646
|
+
"brain.ingest.web.placeholder": "https://...",
|
|
647
|
+
"brain.ingest.folder.pending": "Connecting {path} to Brain.",
|
|
648
|
+
"brain.ingest.folder.saved": "{path} is connected to Brain.",
|
|
649
|
+
"brain.ingest.folder.failed": "Could not add the folder: {reason}",
|
|
650
|
+
"brain.ingest.note.pending": "Saving note to Brain.",
|
|
651
|
+
"brain.ingest.note.saved": "Note was saved to Brain.",
|
|
652
|
+
"brain.ingest.note.failed": "Could not add the note: {reason}",
|
|
653
|
+
"brain.ingest.web.pending": "Reading {url} into Brain.",
|
|
654
|
+
"brain.ingest.web.saved": "{url} was saved to Brain.",
|
|
655
|
+
"brain.ingest.web.failed": "Could not add the web page: {reason}",
|
|
656
|
+
"brain.ingest.type.file": "File",
|
|
657
|
+
"brain.ingest.type.folder": "Folder",
|
|
658
|
+
"brain.ingest.type.note": "Note",
|
|
659
|
+
"brain.ingest.type.web": "Web",
|
|
660
|
+
"brain.ingest.cta.file": "Pick a file to add now",
|
|
661
|
+
"brain.ingest.cta.folder": "Enter a path and press Enter",
|
|
662
|
+
"brain.ingest.cta.note": "Paste content and press Enter",
|
|
663
|
+
"brain.ingest.cta.web": "Enter a URL and press Enter",
|
|
664
|
+
"brain.ingest.active": "Processing {label}",
|
|
665
|
+
"brain.ingest.progress.aria": "Ingestion progress for {label}",
|
|
666
|
+
"brain.ingest.stage.preparing": "Preparing",
|
|
667
|
+
"brain.ingest.stage.parsing": "Parsing",
|
|
668
|
+
"brain.ingest.stage.embedding": "Embedding",
|
|
669
|
+
"brain.ingest.stage.indexing": "Indexing",
|
|
670
|
+
"brain.ingest.stage.complete": "Memorized",
|
|
671
|
+
"brain.ingest.stage.error": "Failed",
|
|
672
|
+
"brain.ingest.stage.preparing.hint": "Reading the source",
|
|
673
|
+
"brain.ingest.stage.parsing.hint": "Extracting text and structure",
|
|
674
|
+
"brain.ingest.stage.embedding.hint": "Turning into semantic vectors",
|
|
675
|
+
"brain.ingest.stage.indexing.hint": "Linking into the knowledge graph",
|
|
676
|
+
"brain.ingest.stage.complete.hint": "It is now part of your knowledge",
|
|
677
|
+
"brain.ingest.result": "{memories} new memories · {entities} new entities",
|
|
678
|
+
"brain.ingest.result.empty": "Merged into existing knowledge",
|
|
679
|
+
"brain.timeline.aria": "Recent memory emergence timeline",
|
|
680
|
+
"brain.timeline.emergenceTitle": "Knowledge that just emerged",
|
|
681
|
+
"brain.timeline.recent": "Recent ingestion",
|
|
682
|
+
"brain.timeline.newMemories": "{count} new memories",
|
|
683
|
+
"brain.timeline.newEntities": "{count} new entities",
|
|
684
|
+
"brain.timeline.at": "{time}",
|
|
685
|
+
"brain.timeline.justNow": "just now",
|
|
686
|
+
"brain.timeline.minutesAgo": "{count}m ago",
|
|
687
|
+
"brain.timeline.empty": "No ingestion yet. Add anything above to begin.",
|
|
427
688
|
"brain.image": "Image",
|
|
428
689
|
"brain.unavailable": "Unavailable",
|
|
429
690
|
"brain.imageAttached": "Image attached",
|
|
@@ -463,6 +724,33 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
463
724
|
"brain.proof.recallEmpty.detail": "No saved memory yet, so Lattice does not show a fake example.",
|
|
464
725
|
"brain.proof.recallPending": "Memory is saved; recall proof is preparing.",
|
|
465
726
|
"brain.proof.recallPending.detail": "When indexing finishes, this slot shows the actual memory Brain can bring back.",
|
|
727
|
+
"brain.modelDemo.aria": "Model switch proof",
|
|
728
|
+
"brain.modelDemo.kicker": "Model-independent Brain",
|
|
729
|
+
"brain.modelDemo.proven": "This memory lives outside the model.",
|
|
730
|
+
"brain.modelDemo.pending": "After the first memory is saved, model-switch proof appears.",
|
|
731
|
+
"brain.modelDemo.detail": "Current model: {model}. Recheck the same question against Brain evidence.",
|
|
732
|
+
"brain.modelDemo.verify": "Recheck same evidence",
|
|
733
|
+
"brain.modelDemo.change": "Switch model",
|
|
734
|
+
"brain.modelDemo.needQuestion": "Ask a question or add memory first, then recheck the same evidence.",
|
|
735
|
+
"brain.modelDemo.checking": "Rechecking the same Brain evidence with {model}.",
|
|
736
|
+
"brain.modelDemo.done": "The same Brain evidence is visible with {model}.",
|
|
737
|
+
"brain.answerProof.aria": "Answer sources and memory proof",
|
|
738
|
+
"brain.answerProof.title": "Memory proof + source citation",
|
|
739
|
+
"brain.answerProof.modelProven": "Brain evidence outside {model}",
|
|
740
|
+
"brain.answerProof.modelPending": "{model} response · evidence pending",
|
|
741
|
+
"brain.answerProof.empty": "No linked source yet. Indexed memory appears here.",
|
|
742
|
+
"brain.citation.chip": "Source {num}",
|
|
743
|
+
"brain.citation.chip.long": "Source {num}: {title}",
|
|
744
|
+
"brain.citation.expand": "Expand source",
|
|
745
|
+
"brain.citation.close": "Close source",
|
|
746
|
+
"brain.citation.preview.from": "From: ",
|
|
747
|
+
"brain.citation.preview.snippet": "Excerpt: ",
|
|
748
|
+
"brain.citation.keyboard.tip": "Press Space or Enter to expand a source, Escape to close.",
|
|
749
|
+
"brain.citation.region": "Source citations referenced in the answer",
|
|
750
|
+
"brain.citation.announce.open": "Opened source {num}: {title}",
|
|
751
|
+
"brain.citation.announce.close": "Closed source preview.",
|
|
752
|
+
"brain.citation.count": "This answer cites {count} source(s).",
|
|
753
|
+
"brain.citation.score": "Relevance {score}%",
|
|
466
754
|
"brain.memory.empty.kicker": "First memory",
|
|
467
755
|
"brain.memory.empty": "Memory is quiet",
|
|
468
756
|
"brain.knowledge.empty": "Knowledge is forming",
|
|
@@ -472,6 +760,24 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
472
760
|
"brain.graph.emptyFocus": "Your Brain graph grows as you add conversations, documents, and projects.",
|
|
473
761
|
"brain.graph.search": "Search",
|
|
474
762
|
"brain.graph.searchAria": "Search knowledge graph",
|
|
763
|
+
"brain.graph.control.panel": "Graph exploration controls",
|
|
764
|
+
"brain.graph.control.filter": "Filter",
|
|
765
|
+
"brain.graph.control.types": "Entity types",
|
|
766
|
+
"brain.graph.control.allTypes": "All types",
|
|
767
|
+
"brain.graph.control.time": "Time exploration",
|
|
768
|
+
"brain.graph.control.dateRange": "Recently added window",
|
|
769
|
+
"brain.graph.control.resetFilters": "Reset filters",
|
|
770
|
+
"brain.graph.control.recentWindow": "Last {days} days",
|
|
771
|
+
"brain.graph.control.allTime": "All time",
|
|
772
|
+
"brain.graph.control.toggleType": "Toggle {type} type",
|
|
773
|
+
"brain.graph.search.typeahead": "Search suggestions",
|
|
774
|
+
"brain.graph.search.typeaheadAria": "Search suggestion results",
|
|
775
|
+
"brain.graph.search.noMatches": "No matching nodes",
|
|
776
|
+
"brain.graph.search.matchCount": "{count} matches",
|
|
777
|
+
"brain.graph.focus.neighbors": "{count} neighbors highlighted",
|
|
778
|
+
"brain.graph.focus.smooth": "Smoothly focuses the selected node and highlights its neighbors.",
|
|
779
|
+
"brain.graph.focus.recent": "Recently added",
|
|
780
|
+
"brain.graph.focus.clear": "Clear focus",
|
|
475
781
|
"care.title": "Care for my Brain",
|
|
476
782
|
"care.subtitle": "Own it locally. Keep it portable.",
|
|
477
783
|
"care.private": "Private",
|
|
@@ -659,6 +965,37 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
659
965
|
"flow.install.step.download": "Download",
|
|
660
966
|
"flow.install.step.validate": "Validate",
|
|
661
967
|
"flow.install.step.load": "Load",
|
|
968
|
+
"flow.analysis.hardware.icon.chip": "🖥️",
|
|
969
|
+
"flow.analysis.hardware.icon.ram": "🧠",
|
|
970
|
+
"flow.analysis.hardware.icon.gpu": "⚡",
|
|
971
|
+
"flow.analysis.hardware.icon.support": "🧩",
|
|
972
|
+
"flow.analysis.hardware.icon.models": "📦",
|
|
973
|
+
"flow.analysis.hardware.label.chip": "Computer (operating system and chip)",
|
|
974
|
+
"flow.analysis.hardware.label.ram": "Memory (working space to think, RAM)",
|
|
975
|
+
"flow.analysis.hardware.label.gpu": "Graphics (the GPU that speeds up math)",
|
|
976
|
+
"flow.analysis.hardware.label.support": "Local support (helpers that run models)",
|
|
977
|
+
"flow.analysis.hardware.label.models": "Models (AI Brains already installed)",
|
|
978
|
+
"flow.recommend.timeEstimate": "Download about {download} · first reply about {response}s",
|
|
979
|
+
"flow.recommend.timeEstimate.ready": "No download needed · first reply about {response}s",
|
|
980
|
+
"flow.recommend.timeEstimate.unknown": "Download time unknown · first reply about {response}s",
|
|
981
|
+
"flow.recommend.timeNote": "Actual time depends on your network speed.",
|
|
982
|
+
"flow.recommend.minutes": "{count} min",
|
|
983
|
+
"flow.recommend.comparison.faster": "(faster)",
|
|
984
|
+
"flow.recommend.comparison.advanced": "(more capable)",
|
|
985
|
+
"flow.recommend.choose": "Choose this model",
|
|
986
|
+
"flow.recommend.primaryNote": "Ready to use in about {time}",
|
|
987
|
+
"flow.recommend.primaryNote.unknown": "Ready to use right after download",
|
|
988
|
+
"flow.recommend.nextHint": "Choosing takes you to download and setup, then your Brain opens automatically.",
|
|
989
|
+
"flow.install.expectedTitle": "What to expect",
|
|
990
|
+
"flow.install.expected": "About {download} to download, then a first reply within about {response}s",
|
|
991
|
+
"flow.install.expected.ready": "No download — first reply within about {response}s",
|
|
992
|
+
"flow.install.expected.unknown": "After download, a first reply within about {response}s",
|
|
993
|
+
"flow.install.timelineStep.download": "Download model",
|
|
994
|
+
"flow.install.timelineStep.validate": "Check the reply",
|
|
995
|
+
"flow.install.timelineStep.load": "Load into Brain",
|
|
996
|
+
"flow.install.timelineApprox": "about {time}",
|
|
997
|
+
"flow.install.timelineQuick": "moment",
|
|
998
|
+
"flow.install.expectedCompletion": "When it finishes, your Brain opens right away.",
|
|
662
999
|
"flow.shell": "Create your local AI Brain",
|
|
663
1000
|
"flow.login.title": "Choose the owner of your AI Brain.",
|
|
664
1001
|
"flow.login.body": "Lattice AI is a local-first Digital Brain that keeps your knowledge on this computer. Models can change; external transfer starts only when you choose it.",
|
|
@@ -725,6 +1062,43 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
725
1062
|
"flow.consent.location": "Storage location",
|
|
726
1063
|
"flow.consent.external": "External target",
|
|
727
1064
|
"flow.consent.externalNone": "No external connection before selection",
|
|
1065
|
+
"brain.answerProof.citationsLabel": "{count} evidence sources",
|
|
1066
|
+
"brain.answerProof.marker": "Jump to source {index}",
|
|
1067
|
+
"brain.answerProof.markerShort": "Source {index}",
|
|
1068
|
+
"brain.answerProof.citationItem": "Source {index}: {title}",
|
|
1069
|
+
"brain.answerProof.modelLine": "Evidence behind this {model} answer",
|
|
1070
|
+
"shell.account.aria": "Account and workspace",
|
|
1071
|
+
"shell.account.workspaceLabel": "Workspace",
|
|
1072
|
+
"shell.account.personal": "Personal Brain",
|
|
1073
|
+
"shell.account.modeLabel": "View mode",
|
|
1074
|
+
"shell.account.mode.basic": "Basic",
|
|
1075
|
+
"shell.account.mode.advanced": "Advanced",
|
|
1076
|
+
"shell.account.mode.admin": "Admin",
|
|
1077
|
+
"shell.account.open": "Open account and workspace menu",
|
|
1078
|
+
"shell.account.menuAria": "Account and workspace menu",
|
|
1079
|
+
"shell.account.profile": "Profile & account",
|
|
1080
|
+
"shell.account.workspaces": "Switch workspace",
|
|
1081
|
+
"shell.account.admin": "Admin console",
|
|
1082
|
+
"shell.account.settings": "Open settings",
|
|
1083
|
+
"shell.sync.aria": "VS Code extension link status",
|
|
1084
|
+
"shell.sync.label": "VS Code",
|
|
1085
|
+
"shell.sync.connected": "Connected",
|
|
1086
|
+
"shell.sync.indexing": "Indexing",
|
|
1087
|
+
"shell.sync.synced": "Synced",
|
|
1088
|
+
"shell.sync.offline": "Not connected",
|
|
1089
|
+
"shell.sync.checking": "Checking",
|
|
1090
|
+
"shell.sync.detail": "The extension and main app share the same Brain.",
|
|
1091
|
+
"shell.sync.detailOffline": "The VS Code extension is not linked to this Brain yet.",
|
|
1092
|
+
"feedback.retry": "Retry",
|
|
1093
|
+
"feedback.error.title": "Something went wrong",
|
|
1094
|
+
"feedback.error.body": "Try again shortly or check the connection in Settings.",
|
|
1095
|
+
"feedback.consent.aria": "External access consent status",
|
|
1096
|
+
"feedback.consent.activeTitle": "External access allowed",
|
|
1097
|
+
"feedback.consent.activeBody": "Models and pages are fetched externally only when needed.",
|
|
1098
|
+
"feedback.consent.revoke": "Revoke external access",
|
|
1099
|
+
"feedback.consent.revokedTitle": "External access revoked",
|
|
1100
|
+
"feedback.consent.revokedBody": "This Brain now runs fully local. Re-enable below to allow external access again.",
|
|
1101
|
+
"feedback.consent.reenable": "Re-enable",
|
|
728
1102
|
},
|
|
729
1103
|
};
|
|
730
1104
|
|
|
@@ -10,11 +10,13 @@ type AppState = {
|
|
|
10
10
|
workspaceId: string | null;
|
|
11
11
|
apiBase: string | null;
|
|
12
12
|
language: Language;
|
|
13
|
+
externalConsent: boolean;
|
|
13
14
|
setTheme: (theme: Theme) => void;
|
|
14
15
|
setMode: (mode: WorkspaceMode) => void;
|
|
15
16
|
setWorkspaceId: (workspaceId: string | null) => void;
|
|
16
17
|
setApiBase: (apiBase: string | null) => void;
|
|
17
18
|
setLanguage: (language: Language) => void;
|
|
19
|
+
setExternalConsent: (externalConsent: boolean) => void;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
function readTheme(): Theme {
|
|
@@ -40,6 +42,14 @@ function readWorkspaceId(): string | null {
|
|
|
40
42
|
return null;
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
function readExternalConsent(): boolean {
|
|
46
|
+
try {
|
|
47
|
+
// Default: external access allowed (matches existing user-initiated download flow).
|
|
48
|
+
return localStorage.getItem("lattice.externalConsent") !== "revoked";
|
|
49
|
+
} catch {}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
function readLanguage(): Language {
|
|
44
54
|
try {
|
|
45
55
|
const saved = localStorage.getItem("lattice.language");
|
|
@@ -55,6 +65,7 @@ export const useAppStore = create<AppState>((set) => ({
|
|
|
55
65
|
workspaceId: readWorkspaceId(),
|
|
56
66
|
apiBase: null,
|
|
57
67
|
language: readLanguage(),
|
|
68
|
+
externalConsent: readExternalConsent(),
|
|
58
69
|
setTheme: (theme) => {
|
|
59
70
|
document.documentElement.dataset.theme = theme;
|
|
60
71
|
try { localStorage.setItem("lattice.theme", theme); } catch {}
|
|
@@ -71,6 +82,10 @@ export const useAppStore = create<AppState>((set) => ({
|
|
|
71
82
|
set({ workspaceId });
|
|
72
83
|
},
|
|
73
84
|
setApiBase: (apiBase) => set({ apiBase }),
|
|
85
|
+
setExternalConsent: (externalConsent) => {
|
|
86
|
+
try { localStorage.setItem("lattice.externalConsent", externalConsent ? "granted" : "revoked"); } catch {}
|
|
87
|
+
set({ externalConsent });
|
|
88
|
+
},
|
|
74
89
|
setLanguage: (language) => {
|
|
75
90
|
document.documentElement.lang = language === "ko" ? "ko" : "en";
|
|
76
91
|
try { localStorage.setItem("lattice.language", language); } catch {}
|