ltcai 7.6.0 → 7.8.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 +39 -34
- package/docs/CHANGELOG.md +39 -0
- package/frontend/src/App.tsx +4 -2
- package/frontend/src/api/client.ts +9 -2
- package/frontend/src/components/LivingBrain.tsx +9 -1
- package/frontend/src/components/ProductFlow.tsx +27 -3
- package/frontend/src/components/onboarding/RecommendationScreen.tsx +33 -26
- package/frontend/src/features/brain/BrainConversation.tsx +214 -94
- package/frontend/src/features/brain/BrainHome.tsx +32 -28
- package/frontend/src/features/review/ReviewInbox.tsx +2 -2
- package/frontend/src/features/review/reviewHelpers.ts +11 -11
- package/frontend/src/i18n.ts +162 -26
- package/frontend/src/pages/Act.tsx +28 -14
- package/frontend/src/pages/Ask.tsx +11 -2
- package/frontend/src/pages/Brain.tsx +12 -2
- package/frontend/src/routes.ts +6 -6
- package/frontend/src/styles.css +592 -25
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/latticeai/services/architecture_readiness.py +25 -7
- package/latticeai/services/product_readiness.py +159 -0
- package/package.json +1 -1
- package/scripts/product_readiness.py +37 -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-CSeeIWB4.js → Act-DOvf59ru.js} +2 -2
- package/static/app/assets/{Act-CSeeIWB4.js.map → Act-DOvf59ru.js.map} +1 -1
- package/static/app/assets/Brain-C7_0mEiI.js +322 -0
- package/static/app/assets/Brain-C7_0mEiI.js.map +1 -0
- package/static/app/assets/Capture-B9Tlhzqr.js +2 -0
- package/static/app/assets/Capture-B9Tlhzqr.js.map +1 -0
- package/static/app/assets/Library-BJPEEm5O.js +2 -0
- package/static/app/assets/{Library-C4zmA8O2.js.map → Library-BJPEEm5O.js.map} +1 -1
- package/static/app/assets/System-D6t9jo9V.js +2 -0
- package/static/app/assets/{System-Da-Kxwiz.js.map → System-D6t9jo9V.js.map} +1 -1
- package/static/app/assets/index-C7g26IF6.css +2 -0
- package/static/app/assets/index-DbcEYJQ2.js +17 -0
- package/static/app/assets/index-DbcEYJQ2.js.map +1 -0
- package/static/app/assets/primitives-CD38lt4n.js +2 -0
- package/static/app/assets/{primitives-CSsF_Ymb.js.map → primitives-CD38lt4n.js.map} +1 -1
- package/static/app/assets/textarea-BZk6ybp5.js +2 -0
- package/static/app/assets/{textarea-CJMFSyfQ.js.map → textarea-BZk6ybp5.js.map} +1 -1
- package/static/app/index.html +2 -2
- package/frontend/src/components/BrainConversation.tsx +0 -533
- package/frontend/src/components/FirstRunGuide.tsx +0 -99
- package/static/app/assets/Brain-D_Ne4YoR.js +0 -322
- package/static/app/assets/Brain-D_Ne4YoR.js.map +0 -1
- package/static/app/assets/Capture-YFRAO4bJ.js +0 -2
- package/static/app/assets/Capture-YFRAO4bJ.js.map +0 -1
- package/static/app/assets/Library-C4zmA8O2.js +0 -2
- package/static/app/assets/System-Da-Kxwiz.js +0 -2
- package/static/app/assets/index-BwmCpRoW.css +0 -2
- package/static/app/assets/index-D1hsexMt.js +0 -17
- package/static/app/assets/index-D1hsexMt.js.map +0 -1
- package/static/app/assets/primitives-CSsF_Ymb.js +0 -2
- package/static/app/assets/textarea-CJMFSyfQ.js +0 -2
package/frontend/src/i18n.ts
CHANGED
|
@@ -39,10 +39,48 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
39
39
|
"brain.aria.overview": "Brain 한눈에 보기",
|
|
40
40
|
"brain.aria.graph": "지식 그래프",
|
|
41
41
|
"brain.title": "Lattice Brain",
|
|
42
|
+
"brain.edition": "정식 제품",
|
|
43
|
+
"brain.edition.tip": "Lattice AI 7.8 — 한눈에 바로 쓰는 디지털 브레인",
|
|
42
44
|
"brain.local": "로컬 우선",
|
|
43
45
|
"brain.portable": "이동 가능",
|
|
44
46
|
"brain.private": "개인 소유",
|
|
45
47
|
"brain.admin": "관리자 콘솔",
|
|
48
|
+
"brain.command.aria": "제품 상태와 다음 행동",
|
|
49
|
+
"brain.command.kicker": "제품 상태판",
|
|
50
|
+
"brain.command.title": "지금 바로 쓸 수 있는 Brain",
|
|
51
|
+
"brain.command.score": "제품 준비도",
|
|
52
|
+
"brain.command.next": "다음 행동",
|
|
53
|
+
"brain.command.next.empty": "첫 자료를 넣고 바로 질문하세요.",
|
|
54
|
+
"brain.command.next.forming": "주제를 열어 기억이 어떻게 묶이는지 확인하세요.",
|
|
55
|
+
"brain.command.next.alive": "근거를 확인하고 필요하면 모델을 바꿔 보세요.",
|
|
56
|
+
"brain.command.metrics": "Brain 제품 지표",
|
|
57
|
+
"brain.command.metric.memories": "기억 {count}개",
|
|
58
|
+
"brain.command.metric.topics": "주제 {count}개",
|
|
59
|
+
"brain.command.metric.sources": "정상 출처 {count}개",
|
|
60
|
+
"brain.command.metric.proof": "근거 {count}개",
|
|
61
|
+
"brain.command.source.empty": "아직 수집 전",
|
|
62
|
+
"brain.command.action.add": "자료 넣기",
|
|
63
|
+
"brain.command.action.find": "주제 확인",
|
|
64
|
+
"brain.command.action.find.detail": "기억이 묶인 구조 보기",
|
|
65
|
+
"brain.command.action.proof": "근거 확인",
|
|
66
|
+
"brain.command.action.own": "소유권 관리",
|
|
67
|
+
"brain.command.action.own.detail": "백업, 복원, 설정",
|
|
68
|
+
"brain.command.signal.local": "로컬 우선",
|
|
69
|
+
"brain.command.signal.private": "명시 동의",
|
|
70
|
+
"brain.command.signal.portable": "백업 가능",
|
|
71
|
+
"brain.chatHome.aria": "Brain Chat Home",
|
|
72
|
+
"brain.chatHome.contextAria": "Brain 상태와 자료 패널",
|
|
73
|
+
"brain.chatHome.headerLine": "대화, 자료, 기억 상태를 한 화면에서 바로 조작합니다.",
|
|
74
|
+
"brain.chatHome.kicker": "Brain Chat Home",
|
|
75
|
+
"brain.chatHome.title": "먼저 질문하고, 필요하면 자료를 넣으세요.",
|
|
76
|
+
"brain.chatHome.body": "입력창과 시작 프롬프트를 첫 화면에 고정하고, 준비도와 수집 상태는 옆에서 조용히 따라오게 했습니다.",
|
|
77
|
+
"brain.chatHome.utility": "자료 넣기와 Brain 상태",
|
|
78
|
+
"shell.route.brain": "Lattice Brain",
|
|
79
|
+
"shell.route.capture": "자료",
|
|
80
|
+
"shell.route.memory": "그래프",
|
|
81
|
+
"shell.route.library": "모델",
|
|
82
|
+
"shell.route.system": "설정",
|
|
83
|
+
"shell.route.act": "실행",
|
|
46
84
|
"shell.workspace.label": "작업공간 및 프로필",
|
|
47
85
|
"shell.workspace.current": "현재 작업공간",
|
|
48
86
|
"shell.workspace.switch": "전환",
|
|
@@ -76,9 +114,11 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
76
114
|
"brain.empty.trail.save": "1. 첫 기억 저장",
|
|
77
115
|
"brain.empty.trail.recall": "2. Brain Home에서 확인",
|
|
78
116
|
"brain.empty.trail.backup": "3. 백업으로 소유",
|
|
79
|
-
"brain.
|
|
80
|
-
"brain.
|
|
81
|
-
"brain.prompt.
|
|
117
|
+
"brain.home.kicker": "Lattice AI — Living Brain",
|
|
118
|
+
"brain.home.line": "대화할수록 선명해지는, 내 로컬 지식의 중심",
|
|
119
|
+
"brain.prompt.remember": "이 목표를 Brain이 영원히 기억하게 해줘: ",
|
|
120
|
+
"brain.prompt.know": "이걸 Brain에 넣고 핵심을 뽑아줘: ",
|
|
121
|
+
"brain.prompt.plan": "과거 결정들을 Brain이 구조화해서 나중에 쉽게 찾게 해줘: ",
|
|
82
122
|
"brain.placeholder": "Brain에게 말하기...",
|
|
83
123
|
"brain.upload.cta": "파일/문서 넣기",
|
|
84
124
|
"brain.upload.ctaShort": "문서",
|
|
@@ -140,7 +180,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
140
180
|
"brain.timeline.minutesAgo": "{count}분 전",
|
|
141
181
|
"brain.timeline.empty": "아직 수집 기록이 없습니다. 위에서 무엇이든 넣어보세요.",
|
|
142
182
|
"brain.image": "이미지",
|
|
143
|
-
"brain.unavailable": "지금은
|
|
183
|
+
"brain.unavailable": "지금은 응답할 수 없습니다",
|
|
144
184
|
"brain.imageAttached": "이미지 첨부됨",
|
|
145
185
|
"brain.send": "보내기",
|
|
146
186
|
"brain.saved": "기억에 저장됨 · 연결된 주제 {topics}개 · 관련 기억 {memories}개",
|
|
@@ -175,7 +215,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
175
215
|
"brain.proof.recall": "방금 Brain이 다시 꺼낸 기억",
|
|
176
216
|
"brain.proof.recallEmpty.kicker": "Brain 증거 자리",
|
|
177
217
|
"brain.proof.recallEmpty.title": "첫 대화 후 여기에 다시 꺼낸 기억이 표시됩니다.",
|
|
178
|
-
"brain.proof.recallEmpty.detail": "아직 저장된 기억이
|
|
218
|
+
"brain.proof.recallEmpty.detail": "아직 저장된 기억이 없어, 예시를 꾸며내는 대신 실제 기억이 쌓이기를 기다립니다.",
|
|
179
219
|
"brain.proof.recallPending": "기억은 저장됐고 recall 증거를 준비 중입니다.",
|
|
180
220
|
"brain.proof.recallPending.detail": "인덱싱이 끝나면 이 자리에서 실제 기억을 다시 보여줍니다.",
|
|
181
221
|
"brain.modelDemo.aria": "모델 교체 증거",
|
|
@@ -330,6 +370,26 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
330
370
|
"review.dismiss": "기각",
|
|
331
371
|
"review.feedback.open": "승인 또는 기각 전까지 항목은 열린 상태로 유지됩니다.",
|
|
332
372
|
"review.action.failed": "{action} 실패",
|
|
373
|
+
"review.filter.status.pending": "대기",
|
|
374
|
+
"review.filter.status.snoozed": "일시 중지",
|
|
375
|
+
"review.filter.status.all": "전체",
|
|
376
|
+
"review.filter.status.approved": "승인됨",
|
|
377
|
+
"review.filter.status.dismissed": "기각됨",
|
|
378
|
+
"review.filter.source.all": "전체 출처",
|
|
379
|
+
"review.filter.source.workflow_run": "워크플로",
|
|
380
|
+
"review.filter.source.trigger": "트리거",
|
|
381
|
+
"review.filter.source.kg_change_digest": "KG 요약",
|
|
382
|
+
"act.kicker": "자동화",
|
|
383
|
+
"act.title": "중요한 변경은 검토하면서 일을 진행합니다.",
|
|
384
|
+
"act.copy": "목표를 맡기고, 각 실행 결과를 확인한 뒤 민감한 작업만 명시적으로 승인하세요.",
|
|
385
|
+
"act.tab.goals": "목표",
|
|
386
|
+
"act.tab.runs": "실행",
|
|
387
|
+
"act.tab.review": "검토함",
|
|
388
|
+
"act.tab.recipes": "레시피",
|
|
389
|
+
"act.tab.safeguards": "보호 장치",
|
|
390
|
+
"act.tab.permissions": "권한",
|
|
391
|
+
"act.tab.hooks": "훅",
|
|
392
|
+
"act.tab.tools": "도구",
|
|
333
393
|
"admin.back": "Brain",
|
|
334
394
|
"admin.aria.console": "Lattice 관리자",
|
|
335
395
|
"admin.kicker": "분리된 관리자 작업공간",
|
|
@@ -470,16 +530,24 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
470
530
|
"flow.install.expectedCompletion": "끝나면 바로 Brain이 열립니다.",
|
|
471
531
|
"flow.shell": "내 로컬 AI 브레인 만들기",
|
|
472
532
|
"flow.wake.aria": "Brain 깨우기",
|
|
473
|
-
"flow.wake.title": "내 Brain을
|
|
474
|
-
"flow.wake.body": "
|
|
533
|
+
"flow.wake.title": "내 지식이 살아나는 Brain을 시작하세요.",
|
|
534
|
+
"flow.wake.body": "Lattice AI는 이 컴퓨터 안에서 내 대화, 문서, 결정이 오래 남는 작업 기억이 되게 합니다. 모델은 바꿔도 Brain은 계속 내 것입니다.",
|
|
535
|
+
"flow.wake.value.aria": "Brain 시작 가치",
|
|
536
|
+
"flow.wake.value.local.k": "완전 로컬",
|
|
537
|
+
"flow.wake.value.local.v": "지식과 대화는 이 컴퓨터에서 먼저 정리됩니다.",
|
|
538
|
+
"flow.wake.value.instant.k": "바로 이해",
|
|
539
|
+
"flow.wake.value.instant.v": "복잡한 설정 대신 3단계로 첫 대화를 엽니다.",
|
|
540
|
+
"flow.wake.value.brain.k": "지속되는 Brain",
|
|
541
|
+
"flow.wake.value.brain.v": "모델을 바꿔도 내 기억과 그래프는 이어집니다.",
|
|
475
542
|
"flow.wake.plan.aria": "Brain 시작 단계",
|
|
476
543
|
"flow.wake.step.identity": "주인 확인",
|
|
477
544
|
"flow.wake.step.check": "컴퓨터 확인",
|
|
478
545
|
"flow.wake.step.voice": "목소리 선택",
|
|
479
|
-
"flow.wake.primary": "Brain 깨우기",
|
|
480
|
-
"flow.wake.existing": "
|
|
481
|
-
"flow.
|
|
482
|
-
"flow.login.
|
|
546
|
+
"flow.wake.primary": "Brain 지금 깨우기",
|
|
547
|
+
"flow.wake.existing": "기존 Brain 열기",
|
|
548
|
+
"flow.wake.startNote": "평균 2분 안에 첫 대화 시작 · 로컬 우선 · 사용자가 제어",
|
|
549
|
+
"flow.login.title": "이 Brain의 주인을 정합니다.",
|
|
550
|
+
"flow.login.body": "프로필은 로컬 Brain의 소유권을 묶는 기준입니다. 기존 Brain이 있으면 새로 만들기 전에 먼저 안전하게 확인합니다.",
|
|
483
551
|
"flow.name": "이름",
|
|
484
552
|
"flow.name.placeholder": "나",
|
|
485
553
|
"flow.email": "이메일",
|
|
@@ -500,8 +568,8 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
500
568
|
"flow.promise.ownership.k": "사용자 소유",
|
|
501
569
|
"flow.promise.ownership.v": "백업, 복원, 이동을 직접 결정합니다.",
|
|
502
570
|
"flow.promise.aria": "Lattice AI 제품 약속",
|
|
503
|
-
"flow.analysis.title": "이
|
|
504
|
-
"flow.analysis.body": "스펙 점수가 아니라, 이 Mac에서 어떤 로컬 AI 브레인 경험이 편한지
|
|
571
|
+
"flow.analysis.title": "이 컴퓨터에 맞는 Brain 경험을 확인합니다.",
|
|
572
|
+
"flow.analysis.body": "스펙 점수가 아니라, 이 Mac에서 어떤 로컬 AI 브레인 경험이 편한지 보여드립니다. 확인은 로컬 상태를 읽는 것이고, 클라우드 모델은 선택 사항입니다.",
|
|
505
573
|
"flow.analysis.finding": "가장 편한 설정을 찾는 중...",
|
|
506
574
|
"flow.analysis.ready": "추천 모델을 바로 시작할 수 있게 준비했습니다.",
|
|
507
575
|
"flow.analysis.wait": "잠시만 기다리면 자동으로 정리됩니다.",
|
|
@@ -512,8 +580,8 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
512
580
|
"flow.analysis.os.windows": "Windows PC",
|
|
513
581
|
"flow.analysis.os.linux": "Linux 컴퓨터",
|
|
514
582
|
"flow.recommend.title": "추천대로 시작하세요.",
|
|
515
|
-
"flow.recommend.body": "모델은 Brain의 현재 목소리입니다.
|
|
516
|
-
"flow.recommend.primary": "
|
|
583
|
+
"flow.recommend.body": "모델은 Brain의 현재 목소리입니다. 추천, 빠른 선택, 강한 선택만 먼저 보여드려 바로 결정할 수 있게 합니다.",
|
|
584
|
+
"flow.recommend.primary": "추천으로 바로 시작",
|
|
517
585
|
"flow.recommend.unsupported": "이 컴퓨터에서 추가 확인이 필요합니다",
|
|
518
586
|
"flow.recommend.back": "뒤로",
|
|
519
587
|
"flow.recommend.skip": "모델 없이 Brain 열기",
|
|
@@ -523,7 +591,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
523
591
|
"flow.recommend.rank.advanced": "고급 선택",
|
|
524
592
|
"flow.recommend.rank.choice": "선택 {index}",
|
|
525
593
|
"flow.install.title": "모델을 설치하고 시작합니다.",
|
|
526
|
-
"flow.install.body": "이 모델이 Brain의 로컬 목소리가 됩니다.
|
|
594
|
+
"flow.install.body": "이 모델이 Brain의 로컬 목소리가 됩니다. 다운로드는 사용자가 시작할 때만 진행되고, 실행과 기억은 이 컴퓨터에서 유지됩니다.",
|
|
527
595
|
"flow.install.wait": "Brain이 사용할 모델을 기다리고 있습니다.",
|
|
528
596
|
"flow.install.prepare": "Brain 준비 중입니다.",
|
|
529
597
|
"flow.install.done": "Brain이 준비되었습니다.",
|
|
@@ -612,10 +680,48 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
612
680
|
"brain.aria.overview": "Brain overview",
|
|
613
681
|
"brain.aria.graph": "Knowledge Graph",
|
|
614
682
|
"brain.title": "Lattice Brain",
|
|
683
|
+
"brain.edition": "Production Ready",
|
|
684
|
+
"brain.edition.tip": "Lattice AI 7.8 — a Digital Brain you can understand and use at a glance",
|
|
615
685
|
"brain.local": "Local-first",
|
|
616
686
|
"brain.portable": "Portable",
|
|
617
687
|
"brain.private": "Private",
|
|
618
688
|
"brain.admin": "Admin Console",
|
|
689
|
+
"brain.command.aria": "Product status and next action",
|
|
690
|
+
"brain.command.kicker": "Product command center",
|
|
691
|
+
"brain.command.title": "A Brain ready to use now",
|
|
692
|
+
"brain.command.score": "Product readiness",
|
|
693
|
+
"brain.command.next": "Next action",
|
|
694
|
+
"brain.command.next.empty": "Add a first source, then ask immediately.",
|
|
695
|
+
"brain.command.next.forming": "Open topics to see how memories are grouping.",
|
|
696
|
+
"brain.command.next.alive": "Verify proof, then switch models when useful.",
|
|
697
|
+
"brain.command.metrics": "Brain product metrics",
|
|
698
|
+
"brain.command.metric.memories": "{count} memories",
|
|
699
|
+
"brain.command.metric.topics": "{count} topics",
|
|
700
|
+
"brain.command.metric.sources": "{count} healthy sources",
|
|
701
|
+
"brain.command.metric.proof": "{count} proof points",
|
|
702
|
+
"brain.command.source.empty": "No ingestion yet",
|
|
703
|
+
"brain.command.action.add": "Add source",
|
|
704
|
+
"brain.command.action.find": "Inspect topics",
|
|
705
|
+
"brain.command.action.find.detail": "See grouped memory structure",
|
|
706
|
+
"brain.command.action.proof": "Verify proof",
|
|
707
|
+
"brain.command.action.own": "Manage ownership",
|
|
708
|
+
"brain.command.action.own.detail": "Backup, restore, settings",
|
|
709
|
+
"brain.command.signal.local": "Local-first",
|
|
710
|
+
"brain.command.signal.private": "Consent gated",
|
|
711
|
+
"brain.command.signal.portable": "Backup ready",
|
|
712
|
+
"brain.chatHome.aria": "Brain Chat Home",
|
|
713
|
+
"brain.chatHome.contextAria": "Brain status and source panel",
|
|
714
|
+
"brain.chatHome.headerLine": "Chat, sources, and memory status are usable from one screen.",
|
|
715
|
+
"brain.chatHome.kicker": "Brain Chat Home",
|
|
716
|
+
"brain.chatHome.title": "Ask first, add sources when you need them.",
|
|
717
|
+
"brain.chatHome.body": "The input and starter prompts stay in the first viewport while readiness and ingestion status follow quietly beside them.",
|
|
718
|
+
"brain.chatHome.utility": "Sources and Brain status",
|
|
719
|
+
"shell.route.brain": "Lattice Brain",
|
|
720
|
+
"shell.route.capture": "Files",
|
|
721
|
+
"shell.route.memory": "Graph",
|
|
722
|
+
"shell.route.library": "Models",
|
|
723
|
+
"shell.route.system": "Settings",
|
|
724
|
+
"shell.route.act": "Act",
|
|
619
725
|
"shell.workspace.label": "Workspace and profile",
|
|
620
726
|
"shell.workspace.current": "Current workspace",
|
|
621
727
|
"shell.workspace.switch": "Switch",
|
|
@@ -649,6 +755,8 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
649
755
|
"brain.empty.trail.save": "1. Save first memory",
|
|
650
756
|
"brain.empty.trail.recall": "2. See it in Brain Home",
|
|
651
757
|
"brain.empty.trail.backup": "3. Own it with backup",
|
|
758
|
+
"brain.home.kicker": "Lattice AI — Living Brain",
|
|
759
|
+
"brain.home.line": "The center of your local knowledge, clearer with every conversation",
|
|
652
760
|
"brain.prompt.remember": "Remember this project goal: ",
|
|
653
761
|
"brain.prompt.know": "Put this document into my Brain and summarize it: ",
|
|
654
762
|
"brain.prompt.plan": "Organize past decisions so I can find them later: ",
|
|
@@ -713,7 +821,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
713
821
|
"brain.timeline.minutesAgo": "{count}m ago",
|
|
714
822
|
"brain.timeline.empty": "No ingestion yet. Add anything above to begin.",
|
|
715
823
|
"brain.image": "Image",
|
|
716
|
-
"brain.unavailable": "
|
|
824
|
+
"brain.unavailable": "Temporarily unavailable",
|
|
717
825
|
"brain.imageAttached": "Image attached",
|
|
718
826
|
"brain.send": "Send",
|
|
719
827
|
"brain.saved": "Saved to memory · {topics} linked topics · {memories} related memories",
|
|
@@ -748,7 +856,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
748
856
|
"brain.proof.recall": "Just recalled by Brain",
|
|
749
857
|
"brain.proof.recallEmpty.kicker": "Brain proof slot",
|
|
750
858
|
"brain.proof.recallEmpty.title": "After your first exchange, recalled memory appears here.",
|
|
751
|
-
"brain.proof.recallEmpty.detail": "No saved memory yet
|
|
859
|
+
"brain.proof.recallEmpty.detail": "No saved memory yet — Lattice waits for real memory instead of inventing a placeholder example.",
|
|
752
860
|
"brain.proof.recallPending": "Memory is saved; recall proof is preparing.",
|
|
753
861
|
"brain.proof.recallPending.detail": "When indexing finishes, this slot shows the actual memory Brain can bring back.",
|
|
754
862
|
"brain.modelDemo.aria": "Model switch proof",
|
|
@@ -903,6 +1011,26 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
903
1011
|
"review.dismiss": "Dismiss",
|
|
904
1012
|
"review.feedback.open": "item stays open until you approve or dismiss.",
|
|
905
1013
|
"review.action.failed": "{action} failed",
|
|
1014
|
+
"review.filter.status.pending": "Pending",
|
|
1015
|
+
"review.filter.status.snoozed": "Snoozed",
|
|
1016
|
+
"review.filter.status.all": "All",
|
|
1017
|
+
"review.filter.status.approved": "Approved",
|
|
1018
|
+
"review.filter.status.dismissed": "Dismissed",
|
|
1019
|
+
"review.filter.source.all": "All sources",
|
|
1020
|
+
"review.filter.source.workflow_run": "Workflow",
|
|
1021
|
+
"review.filter.source.trigger": "Trigger",
|
|
1022
|
+
"review.filter.source.kg_change_digest": "KG digest",
|
|
1023
|
+
"act.kicker": "Automate",
|
|
1024
|
+
"act.title": "Make work move, with a hand on the door.",
|
|
1025
|
+
"act.copy": "Give Lattice a goal, review each run, and approve sensitive actions before anything important changes.",
|
|
1026
|
+
"act.tab.goals": "Goals",
|
|
1027
|
+
"act.tab.runs": "Runs",
|
|
1028
|
+
"act.tab.review": "Review Center",
|
|
1029
|
+
"act.tab.recipes": "Recipes",
|
|
1030
|
+
"act.tab.safeguards": "Safeguards",
|
|
1031
|
+
"act.tab.permissions": "Permissions",
|
|
1032
|
+
"act.tab.hooks": "Hooks",
|
|
1033
|
+
"act.tab.tools": "Tools",
|
|
906
1034
|
"admin.back": "Brain",
|
|
907
1035
|
"admin.aria.console": "Lattice Admin",
|
|
908
1036
|
"admin.kicker": "Separate admin workspace",
|
|
@@ -1043,16 +1171,24 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
1043
1171
|
"flow.install.expectedCompletion": "When it finishes, your Brain opens right away.",
|
|
1044
1172
|
"flow.shell": "Create your local AI Brain",
|
|
1045
1173
|
"flow.wake.aria": "Wake your Brain",
|
|
1046
|
-
"flow.wake.title": "
|
|
1047
|
-
"flow.wake.body": "
|
|
1174
|
+
"flow.wake.title": "Start the Brain where your knowledge comes alive.",
|
|
1175
|
+
"flow.wake.body": "Lattice AI turns your conversations, documents, and decisions into durable working memory on this computer. Models can change while your Brain remains yours.",
|
|
1176
|
+
"flow.wake.value.aria": "Brain startup value",
|
|
1177
|
+
"flow.wake.value.local.k": "Fully local",
|
|
1178
|
+
"flow.wake.value.local.v": "Knowledge and conversations are organized on this computer first.",
|
|
1179
|
+
"flow.wake.value.instant.k": "Clear start",
|
|
1180
|
+
"flow.wake.value.instant.v": "Open the first conversation in three guided steps.",
|
|
1181
|
+
"flow.wake.value.brain.k": "Durable Brain",
|
|
1182
|
+
"flow.wake.value.brain.v": "Your memories and graph continue even when models change.",
|
|
1048
1183
|
"flow.wake.plan.aria": "Brain start steps",
|
|
1049
1184
|
"flow.wake.step.identity": "Confirm owner",
|
|
1050
1185
|
"flow.wake.step.check": "Check computer",
|
|
1051
1186
|
"flow.wake.step.voice": "Choose voice",
|
|
1052
1187
|
"flow.wake.primary": "Wake Brain",
|
|
1053
1188
|
"flow.wake.existing": "Open existing Brain",
|
|
1054
|
-
"flow.
|
|
1055
|
-
"flow.login.
|
|
1189
|
+
"flow.wake.startNote": "First conversation in about 2 minutes · local-first · user controlled",
|
|
1190
|
+
"flow.login.title": "Choose the owner of this Brain.",
|
|
1191
|
+
"flow.login.body": "Your profile anchors ownership of the local Brain. If a Brain already exists here, Lattice checks safely before creating anything new.",
|
|
1056
1192
|
"flow.name": "Name",
|
|
1057
1193
|
"flow.name.placeholder": "You",
|
|
1058
1194
|
"flow.email": "Email",
|
|
@@ -1073,8 +1209,8 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
1073
1209
|
"flow.promise.ownership.k": "User owned",
|
|
1074
1210
|
"flow.promise.ownership.v": "You decide when to back up, restore, or move it.",
|
|
1075
1211
|
"flow.promise.aria": "Lattice AI product promise",
|
|
1076
|
-
"flow.analysis.title": "Checking
|
|
1077
|
-
"flow.analysis.body": "This is not a spec
|
|
1212
|
+
"flow.analysis.title": "Checking the Brain experience for this computer.",
|
|
1213
|
+
"flow.analysis.body": "This is not a spec score. Lattice reads local capability and explains which local AI Brain experience will feel comfortable on this Mac. Cloud models remain optional.",
|
|
1078
1214
|
"flow.analysis.finding": "Finding the easiest setup...",
|
|
1079
1215
|
"flow.analysis.ready": "Your recommended model is ready to start.",
|
|
1080
1216
|
"flow.analysis.wait": "This will be summarized automatically in a moment.",
|
|
@@ -1085,7 +1221,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
1085
1221
|
"flow.analysis.os.windows": "Windows PC",
|
|
1086
1222
|
"flow.analysis.os.linux": "Linux computer",
|
|
1087
1223
|
"flow.recommend.title": "Start with the recommendation.",
|
|
1088
|
-
"flow.recommend.body": "The model is your Brain's current voice.
|
|
1224
|
+
"flow.recommend.body": "The model is your Brain's current voice. Lattice shows the recommendation, a faster choice, and a stronger choice first so you can decide quickly.",
|
|
1089
1225
|
"flow.recommend.primary": "Start with recommendation",
|
|
1090
1226
|
"flow.recommend.unsupported": "This computer needs one more check",
|
|
1091
1227
|
"flow.recommend.back": "Back",
|
|
@@ -1096,7 +1232,7 @@ export const COPY: Record<Language, TextMap> = {
|
|
|
1096
1232
|
"flow.recommend.rank.advanced": "Advanced",
|
|
1097
1233
|
"flow.recommend.rank.choice": "Choice {index}",
|
|
1098
1234
|
"flow.install.title": "Install the model and start.",
|
|
1099
|
-
"flow.install.body": "This model becomes your Brain's local voice.
|
|
1235
|
+
"flow.install.body": "This model becomes your Brain's local voice. Download starts only when you choose it; execution and memory stay on this computer.",
|
|
1100
1236
|
"flow.install.wait": "Waiting for the model your Brain will use.",
|
|
1101
1237
|
"flow.install.prepare": "Preparing your Brain.",
|
|
1102
1238
|
"flow.install.done": "Your Brain is ready.",
|
|
@@ -12,25 +12,27 @@ import { Textarea } from "@/components/ui/textarea";
|
|
|
12
12
|
import { ReviewInbox } from "@/features/review/ReviewInbox";
|
|
13
13
|
import { useAppStore } from "@/store/appStore";
|
|
14
14
|
import { asArray, shortId } from "@/lib/utils";
|
|
15
|
+
import { t } from "@/i18n";
|
|
15
16
|
|
|
16
17
|
type ActTab = "agents" | "runs" | "workflows" | "hooks" | "tools";
|
|
17
18
|
type RunsSubTab = "runs" | "review";
|
|
18
19
|
|
|
19
|
-
const runsSubTabs: Array<{ id: RunsSubTab;
|
|
20
|
-
{ id: "runs",
|
|
21
|
-
{ id: "review",
|
|
20
|
+
const runsSubTabs: Array<{ id: RunsSubTab; labelKey: string }> = [
|
|
21
|
+
{ id: "runs", labelKey: "act.tab.runs" },
|
|
22
|
+
{ id: "review", labelKey: "act.tab.review" },
|
|
22
23
|
];
|
|
23
24
|
|
|
24
|
-
const tabs: Array<{ id: ActTab;
|
|
25
|
-
{ id: "agents",
|
|
26
|
-
{ id: "runs",
|
|
27
|
-
{ id: "workflows",
|
|
28
|
-
{ id: "hooks",
|
|
29
|
-
{ id: "tools",
|
|
25
|
+
const tabs: Array<{ id: ActTab; labelKey: string; advancedLabelKey?: string }> = [
|
|
26
|
+
{ id: "agents", labelKey: "act.tab.goals" },
|
|
27
|
+
{ id: "runs", labelKey: "act.tab.runs" },
|
|
28
|
+
{ id: "workflows", labelKey: "act.tab.recipes" },
|
|
29
|
+
{ id: "hooks", labelKey: "act.tab.safeguards", advancedLabelKey: "act.tab.hooks" },
|
|
30
|
+
{ id: "tools", labelKey: "act.tab.permissions", advancedLabelKey: "act.tab.tools" },
|
|
30
31
|
];
|
|
31
32
|
|
|
32
33
|
export function ActPage({ initialTab }: { initialTab?: string }) {
|
|
33
34
|
const mode = useAppStore((state) => state.mode);
|
|
35
|
+
const language = useAppStore((state) => state.language);
|
|
34
36
|
const [tab, setTab] = React.useState<ActTab>(() => {
|
|
35
37
|
if (initialTab === "review") return "runs";
|
|
36
38
|
return (initialTab as ActTab) || "agents";
|
|
@@ -47,11 +49,18 @@ export function ActPage({ initialTab }: { initialTab?: string }) {
|
|
|
47
49
|
return (
|
|
48
50
|
<div className="space-y-5">
|
|
49
51
|
<header className="page-hero">
|
|
50
|
-
<div className="page-kicker"><Workflow className="h-4 w-4" />
|
|
51
|
-
<h1 className="page-title">
|
|
52
|
-
<p className="page-copy">
|
|
52
|
+
<div className="page-kicker"><Workflow className="h-4 w-4" /> {t(language, "act.kicker")}</div>
|
|
53
|
+
<h1 className="page-title">{t(language, "act.title")}</h1>
|
|
54
|
+
<p className="page-copy">{t(language, "act.copy")}</p>
|
|
53
55
|
</header>
|
|
54
|
-
<Tabs
|
|
56
|
+
<Tabs
|
|
57
|
+
tabs={tabs.map((item) => ({
|
|
58
|
+
id: item.id,
|
|
59
|
+
label: t(language, mode === "basic" || !item.advancedLabelKey ? item.labelKey : item.advancedLabelKey),
|
|
60
|
+
}))}
|
|
61
|
+
value={tab}
|
|
62
|
+
onChange={(id) => setTab(id as ActTab)}
|
|
63
|
+
/>
|
|
55
64
|
{tab === "agents" ? <AgentsPanel /> : null}
|
|
56
65
|
{tab === "runs" ? <RunsPanel subTab={runsSubTab} onSubTabChange={setRunsSubTab} /> : null}
|
|
57
66
|
{tab === "workflows" ? <WorkflowsPanel /> : null}
|
|
@@ -140,9 +149,14 @@ function AgentsPanel() {
|
|
|
140
149
|
}
|
|
141
150
|
|
|
142
151
|
function RunsPanel({ subTab, onSubTabChange }: { subTab: RunsSubTab; onSubTabChange: (tab: RunsSubTab) => void }) {
|
|
152
|
+
const language = useAppStore((state) => state.language);
|
|
143
153
|
return (
|
|
144
154
|
<div className="space-y-4">
|
|
145
|
-
<Tabs
|
|
155
|
+
<Tabs
|
|
156
|
+
tabs={runsSubTabs.map((item) => ({ id: item.id, label: t(language, item.labelKey) }))}
|
|
157
|
+
value={subTab}
|
|
158
|
+
onChange={(id) => onSubTabChange(id as RunsSubTab)}
|
|
159
|
+
/>
|
|
146
160
|
{subTab === "runs" ? <RunsListPanel /> : <ReviewInbox />}
|
|
147
161
|
</div>
|
|
148
162
|
);
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type BrainState } from "@/components/LivingBrain";
|
|
3
|
+
import { BrainHome } from "@/features/brain/BrainHome";
|
|
2
4
|
|
|
3
5
|
export function AskPage() {
|
|
4
|
-
|
|
6
|
+
const [brainPresence, setBrainPresence] = React.useState<{ state: BrainState; intensity: number }>({
|
|
7
|
+
state: "idle",
|
|
8
|
+
intensity: 0.58,
|
|
9
|
+
});
|
|
10
|
+
const setBrain = React.useCallback((state: BrainState, intensity = 0.58) => {
|
|
11
|
+
setBrainPresence({ state, intensity });
|
|
12
|
+
}, []);
|
|
13
|
+
return <BrainHome brainState={brainPresence.state} intensity={brainPresence.intensity} onBrainChange={setBrain} />;
|
|
5
14
|
}
|
|
@@ -3,13 +3,14 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
3
3
|
import cytoscape, { Core, ElementDefinition } from "cytoscape";
|
|
4
4
|
import { BrainCircuit, DatabaseBackup, Filter, Focus, Layers3, LocateFixed, Search, Sparkles } from "lucide-react";
|
|
5
5
|
import { latticeApi } from "@/api/client";
|
|
6
|
-
import {
|
|
6
|
+
import { type BrainState } from "@/components/LivingBrain";
|
|
7
7
|
import { ActionButton, DataPanel, EmptyState, EntityList, KeyValueList, LoadingPanel, OperationResult, StatGrid, StructuredView, Tabs } from "@/components/primitives";
|
|
8
8
|
import { Badge } from "@/components/ui/badge";
|
|
9
9
|
import { Button } from "@/components/ui/button";
|
|
10
10
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
11
11
|
import { Input } from "@/components/ui/input";
|
|
12
12
|
import { Textarea } from "@/components/ui/textarea";
|
|
13
|
+
import { BrainHome } from "@/features/brain/BrainHome";
|
|
13
14
|
import { useAppStore } from "@/store/appStore";
|
|
14
15
|
import { asArray, fmtNumber, pct, shortId, titleize } from "@/lib/utils";
|
|
15
16
|
|
|
@@ -416,9 +417,16 @@ export function BrainPage({ initialTab }: { initialTab?: string }) {
|
|
|
416
417
|
const mode = useAppStore((state) => state.mode);
|
|
417
418
|
const normalizedInitialTab = normalizeBrainTab(initialTab);
|
|
418
419
|
const [tab, setTab] = React.useState<BrainTab>(normalizedInitialTab);
|
|
420
|
+
const [brainPresence, setBrainPresence] = React.useState<{ state: BrainState; intensity: number }>({
|
|
421
|
+
state: "idle",
|
|
422
|
+
intensity: 0.58,
|
|
423
|
+
});
|
|
419
424
|
React.useEffect(() => {
|
|
420
425
|
setTab(normalizeBrainTab(initialTab));
|
|
421
426
|
}, [initialTab]);
|
|
427
|
+
const setBrain = React.useCallback((state: BrainState, intensity = 0.58) => {
|
|
428
|
+
setBrainPresence({ state, intensity });
|
|
429
|
+
}, []);
|
|
422
430
|
const graph = useQuery({ queryKey: ["graph"], queryFn: latticeApi.graph });
|
|
423
431
|
const stats = useQuery({ queryKey: ["graphStats"], queryFn: latticeApi.graphStats });
|
|
424
432
|
const index = useQuery({ queryKey: ["index"], queryFn: latticeApi.indexStatus });
|
|
@@ -442,7 +450,9 @@ export function BrainPage({ initialTab }: { initialTab?: string }) {
|
|
|
442
450
|
)}
|
|
443
451
|
<Tabs tabs={tabs} value={tab} onChange={(id) => setTab(id as BrainTab)} />
|
|
444
452
|
|
|
445
|
-
{tab === "conversation" ?
|
|
453
|
+
{tab === "conversation" ? (
|
|
454
|
+
<BrainHome brainState={brainPresence.state} intensity={brainPresence.intensity} onBrainChange={setBrain} />
|
|
455
|
+
) : null}
|
|
446
456
|
{tab === "memory" ? <MemoryPanel /> : null}
|
|
447
457
|
{tab === "knowledge" ? <HybridSearch /> : null}
|
|
448
458
|
{tab === "relationships" ? (
|
package/frontend/src/routes.ts
CHANGED
|
@@ -12,12 +12,12 @@ export type PrimaryRoute = "brain" | "memory" | "capture" | "act" | "library" |
|
|
|
12
12
|
export type RouteTarget = { primary: PrimaryRoute; tab?: string };
|
|
13
13
|
|
|
14
14
|
export const productShellRoutes = [
|
|
15
|
-
{ id: "brain", path: "brain",
|
|
16
|
-
{ id: "capture", path: "capture",
|
|
17
|
-
{ id: "memory", path: "knowledge-graph",
|
|
18
|
-
{ id: "library", path: "models",
|
|
19
|
-
{ id: "system", path: "settings",
|
|
20
|
-
{ id: "act", path: "review",
|
|
15
|
+
{ id: "brain", path: "brain", labelKey: "shell.route.brain", icon: Brain, description: "Talk with your living Brain" },
|
|
16
|
+
{ id: "capture", path: "capture", labelKey: "shell.route.capture", icon: FolderInput, description: "Bring in files, folders, and pages" },
|
|
17
|
+
{ id: "memory", path: "knowledge-graph", labelKey: "shell.route.memory", icon: Database, description: "Search and inspect Brain knowledge" },
|
|
18
|
+
{ id: "library", path: "models", labelKey: "shell.route.library", icon: Library, description: "Choose the local model powering your Brain" },
|
|
19
|
+
{ id: "system", path: "settings", labelKey: "shell.route.system", icon: Settings, description: "Keep your Brain safe and portable" },
|
|
20
|
+
{ id: "act", path: "review", labelKey: "shell.route.act", icon: Workflow, description: "Turn goals into supervised runs" },
|
|
21
21
|
] as const;
|
|
22
22
|
|
|
23
23
|
export const directProductRoutes: Record<string, RouteTarget> = {
|