ltcai 8.0.0 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -72
- package/docs/CHANGELOG.md +52 -874
- package/docs/DEVELOPMENT.md +26 -3
- package/docs/LEGACY_COMPATIBILITY.md +3 -1
- package/docs/TRUST_MODEL.md +26 -26
- package/docs/WHY_LATTICE.md +28 -25
- package/docs/kg-schema.md +6 -4
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/embeddings.py +9 -1
- package/lattice_brain/graph/schema.py +6 -0
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/computer_use.py +2 -0
- package/latticeai/api/memory.py +13 -0
- package/latticeai/app_factory.py +43 -162
- package/latticeai/brain/__init__.py +1 -1
- package/latticeai/core/config.py +10 -0
- package/latticeai/core/local_embeddings.py +8 -0
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/mcp_registry.py +140 -1
- package/latticeai/core/tool_registry.py +10 -0
- package/latticeai/core/workspace_graph_trace.py +132 -0
- package/latticeai/core/workspace_memory.py +75 -0
- package/latticeai/core/workspace_os.py +135 -1283
- package/latticeai/core/workspace_os_utils.py +132 -0
- package/latticeai/core/workspace_permissions.py +99 -0
- package/latticeai/core/workspace_plugins.py +97 -0
- package/latticeai/core/workspace_runs.py +612 -0
- package/latticeai/core/workspace_skills.py +114 -0
- package/latticeai/core/workspace_snapshots.py +195 -0
- package/latticeai/core/workspace_timeline.py +107 -0
- package/latticeai/runtime/audit_runtime.py +64 -0
- package/latticeai/runtime/config_runtime.py +4 -0
- package/latticeai/runtime/sso_runtime.py +52 -0
- package/latticeai/services/architecture_readiness.py +6 -5
- package/latticeai/services/memory_service.py +215 -7
- package/latticeai/services/model_capability_registry.py +68 -0
- package/latticeai/services/model_engines.py +603 -0
- package/latticeai/services/model_loading.py +482 -0
- package/latticeai/services/model_recommendation.py +5 -0
- package/latticeai/services/model_runtime.py +146 -837
- package/latticeai/services/product_readiness.py +19 -18
- package/package.json +2 -2
- package/scripts/build_frontend_assets.mjs +11 -2
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/tauri.conf.json +1 -1
- package/static/app/asset-manifest.json +11 -102
- package/static/app/assets/Act-D9jIknFd.js +1 -0
- package/static/app/assets/Brain-CFOtWbPN.js +321 -0
- package/static/app/assets/{Capture-B9Tlhzqr.js → Capture-Q4WYzwr5.js} +1 -2
- package/static/app/assets/Library-C5Q2yWee.js +1 -0
- package/static/app/assets/System-BLbjdr1_.js +1 -0
- package/static/app/assets/core-CwxXejkd.js +1 -2
- package/static/app/assets/index-BqammyNu.js +16 -0
- package/static/app/assets/index-ty1iGgZu.css +2 -0
- package/static/app/assets/primitives-Br8uSfZ4.js +1 -0
- package/static/app/assets/{textarea-BZk6ybp5.js → textarea-BnhNs1_X.js} +1 -2
- package/static/app/index.html +3 -10
- package/static/app/theme-boot.js +8 -0
- package/static/sw.js +1 -1
- package/tools/__init__.py +2 -1
- package/tools/computer.py +21 -0
- package/docs/CARRYOVER_AUDIT_v3.6.0.md +0 -61
- package/docs/HANDOVER_v3.6.0.md +0 -46
- package/docs/RUNTIME_HOOK_COVERAGE_v3.5.0.md +0 -56
- package/docs/RUNTIME_HOOK_COVERAGE_v3.6.0.md +0 -49
- package/docs/V2_ARCHITECTURE.md +0 -561
- package/docs/V3_2_AUDIT.md +0 -82
- package/docs/V3_BACKEND_ARCHITECTURE.md +0 -138
- package/docs/V3_FRONTEND.md +0 -140
- package/docs/V4_1_FRONTEND_ARCHITECTURE_REVIEW.md +0 -65
- package/docs/V4_1_FRONTEND_MIGRATION_REPORT.md +0 -70
- package/docs/V4_1_VALIDATION_REPORT.md +0 -47
- package/docs/V4_2_BRAIN_CORE_ARCHITECTURE.md +0 -97
- package/docs/V4_2_STORAGE_MIGRATION_REPORT.md +0 -91
- package/docs/V4_2_VALIDATION_REPORT.md +0 -89
- package/docs/V4_3_2_DEADCODE_AUDIT_REPORT.md +0 -174
- package/docs/V4_3_2_DOCUMENTATION_CLEANUP_REPORT.md +0 -81
- package/docs/V4_3_2_GITHUB_VERCEL_CHECK_REPORT.md +0 -75
- package/docs/V4_3_2_GRAPH_UX_REPORT.md +0 -48
- package/docs/V4_3_2_INDEPENDENT_AUDIT_PACKAGE.md +0 -209
- package/docs/V4_3_2_PRODUCT_POLISH_REPORT.md +0 -57
- package/docs/V4_3_2_SELF_AUDIT_REPORT.md +0 -63
- package/docs/V4_3_2_VALIDATION_REPORT.md +0 -97
- package/docs/V4_3_3_VALIDATION_REPORT.md +0 -46
- package/docs/V4_3_PORTABILITY_ARCHITECTURE.md +0 -69
- package/docs/V4_3_PRIVACY_AUDIT.md +0 -60
- package/docs/V4_3_PRODUCT_HARDENING_REPORT.md +0 -53
- package/docs/V4_3_VALIDATION_REPORT.md +0 -58
- package/docs/V4_4_0_EXTRACTION_REPORT.md +0 -239
- package/docs/V4_5_0_GEMMA_RUNTIME_COMPATIBILITY_REPORT.md +0 -49
- package/docs/V4_5_0_GRAPH_UX_REPORT.md +0 -34
- package/docs/V4_5_0_MODEL_RUNTIME_UX_REPORT.md +0 -40
- package/docs/V4_5_0_ONBOARDING_REPORT.md +0 -31
- package/docs/V4_5_0_PRODUCT_EXPERIENCE_RECOVERY_REPORT.md +0 -49
- package/docs/V4_5_0_VALIDATION_REPORT.md +0 -60
- package/docs/V4_5_1_GRAPH_EXPERIENCE_REPORT.md +0 -33
- package/docs/V4_5_1_MODEL_EXPERIENCE_REPORT.md +0 -37
- package/docs/V4_5_1_NAVIGATION_REPORT.md +0 -37
- package/docs/V4_5_1_ONBOARDING_REPORT.md +0 -29
- package/docs/V4_5_1_PRODUCT_REIMAGINING_REPORT.md +0 -61
- package/docs/V4_5_1_RC_ARTIFACTS.md +0 -44
- package/docs/V4_5_1_UX_REPORT.md +0 -45
- package/docs/V4_5_1_VALIDATION_REPORT.md +0 -55
- package/docs/V4_5_1_VISUAL_DESIGN_REPORT.md +0 -30
- package/docs/V4_6_0_LIVING_BRAIN_EXPERIENCE_REPORT.md +0 -72
- package/docs/V4_6_1_RELEASE_REFRESH_REPORT.md +0 -42
- package/docs/V4_7_0_ADMIN_SEPARATION_REPORT.md +0 -42
- package/docs/V4_7_1_ADMIN_OPERATIONS_REPORT.md +0 -49
- package/docs/V4_7_2_INTUITIVE_BRAIN_UX_REPORT.md +0 -62
- package/docs/V4_BRAIN_ARCHITECTURE.md +0 -322
- package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +0 -555
- package/docs/V4_IMPLEMENTATION_PLAN.md +0 -470
- package/frontend/index.html +0 -24
- package/frontend/openapi.json +0 -15425
- package/frontend/src/App.tsx +0 -243
- package/frontend/src/api/client.ts +0 -580
- package/frontend/src/api/openapi.ts +0 -17892
- package/frontend/src/components/AdminAccessGate.tsx +0 -70
- package/frontend/src/components/FeedbackState.tsx +0 -45
- package/frontend/src/components/LanguageSwitcher.tsx +0 -23
- package/frontend/src/components/LivingBrain.tsx +0 -220
- package/frontend/src/components/ProductFlow.tsx +0 -171
- package/frontend/src/components/WorkspaceProfileSwitcher.tsx +0 -176
- package/frontend/src/components/onboarding/AnalysisScreen.tsx +0 -135
- package/frontend/src/components/onboarding/DownloadConsentPanel.tsx +0 -29
- package/frontend/src/components/onboarding/InstallScreen.tsx +0 -263
- package/frontend/src/components/onboarding/LanguageChooser.tsx +0 -23
- package/frontend/src/components/onboarding/LoginScreen.tsx +0 -131
- package/frontend/src/components/onboarding/ProductFlowScreens.tsx +0 -13
- package/frontend/src/components/onboarding/RecommendationScreen.tsx +0 -116
- package/frontend/src/components/onboarding/recommendationModel.ts +0 -189
- package/frontend/src/components/primitives.tsx +0 -392
- package/frontend/src/components/ui/badge.tsx +0 -27
- package/frontend/src/components/ui/button.tsx +0 -37
- package/frontend/src/components/ui/card.tsx +0 -22
- package/frontend/src/components/ui/input.tsx +0 -16
- package/frontend/src/components/ui/textarea.tsx +0 -16
- package/frontend/src/features/admin/AdminConsole.tsx +0 -334
- package/frontend/src/features/brain/BrainCarePanel.tsx +0 -254
- package/frontend/src/features/brain/BrainComposer.tsx +0 -85
- package/frontend/src/features/brain/BrainConversation.tsx +0 -688
- package/frontend/src/features/brain/BrainGraphLayer.tsx +0 -365
- package/frontend/src/features/brain/BrainHome.tsx +0 -624
- package/frontend/src/features/brain/BrainMemoryLayer.tsx +0 -45
- package/frontend/src/features/brain/BrainOverviewPanel.tsx +0 -149
- package/frontend/src/features/brain/BrainRelationshipLayer.tsx +0 -43
- package/frontend/src/features/brain/DepthEmergence.tsx +0 -53
- package/frontend/src/features/brain/brainData.ts +0 -246
- package/frontend/src/features/brain/graphLayout.ts +0 -37
- package/frontend/src/features/brain/types.ts +0 -150
- package/frontend/src/features/review/ReviewCard.tsx +0 -100
- package/frontend/src/features/review/ReviewInbox.tsx +0 -127
- package/frontend/src/features/review/reviewHelpers.ts +0 -69
- package/frontend/src/i18n.ts +0 -1303
- package/frontend/src/lib/utils.ts +0 -33
- package/frontend/src/main.tsx +0 -23
- package/frontend/src/pages/Act.tsx +0 -458
- package/frontend/src/pages/Ask.tsx +0 -14
- package/frontend/src/pages/Brain.tsx +0 -914
- package/frontend/src/pages/Capture.tsx +0 -258
- package/frontend/src/pages/Library.tsx +0 -486
- package/frontend/src/pages/System.tsx +0 -621
- package/frontend/src/routes.ts +0 -92
- package/frontend/src/store/appStore.ts +0 -94
- package/frontend/src/styles.css +0 -6579
- package/static/app/assets/Act-DOvf59ru.js +0 -2
- package/static/app/assets/Act-DOvf59ru.js.map +0 -1
- package/static/app/assets/Brain-C7_0mEiI.js +0 -322
- package/static/app/assets/Brain-C7_0mEiI.js.map +0 -1
- package/static/app/assets/Capture-B9Tlhzqr.js.map +0 -1
- package/static/app/assets/Library-BJPEEm5O.js +0 -2
- package/static/app/assets/Library-BJPEEm5O.js.map +0 -1
- package/static/app/assets/System-D6t9jo9V.js +0 -2
- package/static/app/assets/System-D6t9jo9V.js.map +0 -1
- package/static/app/assets/core-CwxXejkd.js.map +0 -1
- package/static/app/assets/index-C7g26IF6.css +0 -2
- package/static/app/assets/index-DbcEYJQ2.js +0 -17
- package/static/app/assets/index-DbcEYJQ2.js.map +0 -1
- package/static/app/assets/primitives-CD38lt4n.js +0 -2
- package/static/app/assets/primitives-CD38lt4n.js.map +0 -1
- package/static/app/assets/textarea-BZk6ybp5.js.map +0 -1
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { BrainCircuit, DatabaseZap, Repeat2 } from "lucide-react";
|
|
3
|
-
import { t } from "@/i18n";
|
|
4
|
-
import { useAppStore } from "@/store/appStore";
|
|
5
|
-
import type { BrainDepth, BrainProof, BrainReadiness, KnowledgeConcept, MemoryFragment } from "./types";
|
|
6
|
-
|
|
7
|
-
export function BrainOverviewPanel({
|
|
8
|
-
memories,
|
|
9
|
-
concepts,
|
|
10
|
-
readiness,
|
|
11
|
-
proof,
|
|
12
|
-
onOpenDepth,
|
|
13
|
-
}: {
|
|
14
|
-
memories: MemoryFragment[];
|
|
15
|
-
concepts: KnowledgeConcept[];
|
|
16
|
-
readiness: BrainReadiness;
|
|
17
|
-
proof: BrainProof;
|
|
18
|
-
onOpenDepth: (depth: BrainDepth) => void;
|
|
19
|
-
}) {
|
|
20
|
-
const language = useAppStore((state) => state.language);
|
|
21
|
-
const recent = memories.slice(0, 3);
|
|
22
|
-
const older = memories.slice(3, 6);
|
|
23
|
-
const topics = concepts.slice(0, 4);
|
|
24
|
-
const hasDurableProof = proof.proofs.hasDurableEvidence || proof.modelContinuity.proven;
|
|
25
|
-
const hasRecallProof = proof.recall.items.length > 0;
|
|
26
|
-
const modelProofValue = proof.modelContinuity.proven && proof.claims.keepsContextAcrossModels
|
|
27
|
-
? proof.modelContinuity.activeModel || t(language, "brain.proof.noModel")
|
|
28
|
-
: t(language, "brain.proof.modelPending");
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<section className="brain-overview-panel" aria-label={t(language, "brain.aria.overview")}>
|
|
32
|
-
<div className="brain-overview-head">
|
|
33
|
-
<div>
|
|
34
|
-
<span>{t(language, "brain.overview.kicker")}</span>
|
|
35
|
-
<strong>{t(language, "brain.overview.title")}</strong>
|
|
36
|
-
</div>
|
|
37
|
-
<button type="button" onClick={() => onOpenDepth(5)}>{t(language, "brain.overview.graph")}</button>
|
|
38
|
-
</div>
|
|
39
|
-
<div className="brain-overview-grid">
|
|
40
|
-
<BrainOverviewColumn
|
|
41
|
-
title={t(language, "brain.overview.recent")}
|
|
42
|
-
empty={t(language, "brain.overview.recentEmpty")}
|
|
43
|
-
items={recent.map((memory) => memory.title)}
|
|
44
|
-
onOpen={() => onOpenDepth(2)}
|
|
45
|
-
/>
|
|
46
|
-
<BrainOverviewColumn
|
|
47
|
-
title={t(language, "brain.overview.older")}
|
|
48
|
-
empty={t(language, "brain.overview.olderEmpty")}
|
|
49
|
-
items={older.map((memory) => memory.title)}
|
|
50
|
-
onOpen={() => onOpenDepth(2)}
|
|
51
|
-
/>
|
|
52
|
-
<BrainOverviewColumn
|
|
53
|
-
title={t(language, "brain.overview.topics")}
|
|
54
|
-
empty={t(language, "brain.overview.topicsEmpty")}
|
|
55
|
-
items={topics.map((concept) => concept.label)}
|
|
56
|
-
onOpen={() => onOpenDepth(3)}
|
|
57
|
-
/>
|
|
58
|
-
</div>
|
|
59
|
-
<div className="brain-readiness-strip" data-state={readiness.state}>
|
|
60
|
-
<div>
|
|
61
|
-
<span>{t(language, "brain.readiness.kicker")}</span>
|
|
62
|
-
<strong>{t(language, readiness.titleKey)}</strong>
|
|
63
|
-
</div>
|
|
64
|
-
<div className="brain-readiness-meter" aria-label={t(language, "brain.readiness.aria")}>
|
|
65
|
-
<i style={{ width: `${readiness.score}%` }} />
|
|
66
|
-
</div>
|
|
67
|
-
<button type="button" onClick={() => onOpenDepth(readiness.depth)}>
|
|
68
|
-
{t(language, readiness.actionKey)}
|
|
69
|
-
</button>
|
|
70
|
-
</div>
|
|
71
|
-
<div className="brain-proof-strip" aria-label={t(language, "brain.proof.aria")}>
|
|
72
|
-
<BrainProofPoint
|
|
73
|
-
icon={<DatabaseZap className="h-4 w-4" />}
|
|
74
|
-
label={t(language, "brain.proof.context")}
|
|
75
|
-
value={hasDurableProof
|
|
76
|
-
? t(language, "brain.proof.contextValue", { count: proof.proofs.durableItems })
|
|
77
|
-
: t(language, "brain.proof.contextEmpty")}
|
|
78
|
-
/>
|
|
79
|
-
<BrainProofPoint
|
|
80
|
-
icon={<Repeat2 className="h-4 w-4" />}
|
|
81
|
-
label={t(language, "brain.proof.model")}
|
|
82
|
-
value={modelProofValue}
|
|
83
|
-
/>
|
|
84
|
-
<BrainProofPoint
|
|
85
|
-
icon={<BrainCircuit className="h-4 w-4" />}
|
|
86
|
-
label={t(language, "brain.proof.store")}
|
|
87
|
-
value={t(language, "brain.proof.storeValue", {
|
|
88
|
-
topics: proof.proofs.graphConcepts,
|
|
89
|
-
vectors: proof.proofs.vectorItems,
|
|
90
|
-
})}
|
|
91
|
-
/>
|
|
92
|
-
</div>
|
|
93
|
-
{hasRecallProof ? (
|
|
94
|
-
<button type="button" className="brain-recall-proof" onClick={() => onOpenDepth(2)}>
|
|
95
|
-
<span>{t(language, "brain.proof.recall")}</span>
|
|
96
|
-
<strong>{proof.recall.items[0].title}</strong>
|
|
97
|
-
<small>{proof.recall.items[0].snippet || proof.recall.query}</small>
|
|
98
|
-
</button>
|
|
99
|
-
) : (
|
|
100
|
-
<div className="brain-recall-proof is-empty" role="status">
|
|
101
|
-
<span>{t(language, "brain.proof.recallEmpty.kicker")}</span>
|
|
102
|
-
<strong>{t(language, hasDurableProof ? "brain.proof.recallPending" : "brain.proof.recallEmpty.title")}</strong>
|
|
103
|
-
<small>{t(language, hasDurableProof ? "brain.proof.recallPending.detail" : "brain.proof.recallEmpty.detail")}</small>
|
|
104
|
-
</div>
|
|
105
|
-
)}
|
|
106
|
-
</section>
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function BrainProofPoint({
|
|
111
|
-
icon,
|
|
112
|
-
label,
|
|
113
|
-
value,
|
|
114
|
-
}: {
|
|
115
|
-
icon: React.ReactNode;
|
|
116
|
-
label: string;
|
|
117
|
-
value: string;
|
|
118
|
-
}) {
|
|
119
|
-
return (
|
|
120
|
-
<div className="brain-proof-point">
|
|
121
|
-
{icon}
|
|
122
|
-
<span>{label}</span>
|
|
123
|
-
<strong>{value}</strong>
|
|
124
|
-
</div>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function BrainOverviewColumn({
|
|
129
|
-
title,
|
|
130
|
-
empty,
|
|
131
|
-
items,
|
|
132
|
-
onOpen,
|
|
133
|
-
}: {
|
|
134
|
-
title: string;
|
|
135
|
-
empty: string;
|
|
136
|
-
items: string[];
|
|
137
|
-
onOpen: () => void;
|
|
138
|
-
}) {
|
|
139
|
-
return (
|
|
140
|
-
<button type="button" className="brain-overview-column" onClick={onOpen}>
|
|
141
|
-
<span>{title}</span>
|
|
142
|
-
{items.length ? (
|
|
143
|
-
items.slice(0, 3).map((item) => <strong key={item}>{item}</strong>)
|
|
144
|
-
) : (
|
|
145
|
-
<em>{empty}</em>
|
|
146
|
-
)}
|
|
147
|
-
</button>
|
|
148
|
-
);
|
|
149
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { KnowledgeConcept, RelationshipThread } from "./types";
|
|
2
|
-
import { layoutGraphNodes } from "./graphLayout";
|
|
3
|
-
|
|
4
|
-
export function BrainRelationshipLayer({
|
|
5
|
-
concepts,
|
|
6
|
-
relationships,
|
|
7
|
-
}: {
|
|
8
|
-
concepts: KnowledgeConcept[];
|
|
9
|
-
relationships: RelationshipThread[];
|
|
10
|
-
}) {
|
|
11
|
-
const visibleConcepts = concepts.slice(0, 10);
|
|
12
|
-
const layout = layoutGraphNodes(visibleConcepts, 30, 20);
|
|
13
|
-
const positionById = new Map(layout.map((item) => [item.node.id, item]));
|
|
14
|
-
const visibleRelationships = relationships
|
|
15
|
-
.map((relationship, index) => {
|
|
16
|
-
const source = positionById.get(relationship.source) || layout[index % Math.max(layout.length, 1)];
|
|
17
|
-
const target = positionById.get(relationship.target) || layout[(index + 3) % Math.max(layout.length, 1)];
|
|
18
|
-
return source && target && source.node.id !== target.node.id ? { relationship, source, target } : null;
|
|
19
|
-
})
|
|
20
|
-
.filter(Boolean)
|
|
21
|
-
.slice(0, 8) as Array<{
|
|
22
|
-
relationship: RelationshipThread;
|
|
23
|
-
source: ReturnType<typeof layoutGraphNodes>[number];
|
|
24
|
-
target: ReturnType<typeof layoutGraphNodes>[number];
|
|
25
|
-
}>;
|
|
26
|
-
|
|
27
|
-
if (!visibleRelationships.length) return null;
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<svg className="relationship-weave" viewBox="0 0 100 100" aria-hidden>
|
|
31
|
-
{visibleRelationships.map(({ relationship, source, target }, index) => (
|
|
32
|
-
<line
|
|
33
|
-
key={`${relationship.id}-${index}`}
|
|
34
|
-
x1={source.x}
|
|
35
|
-
y1={source.y}
|
|
36
|
-
x2={target.x}
|
|
37
|
-
y2={target.y}
|
|
38
|
-
style={{ animationDelay: `${index * 80}ms` }}
|
|
39
|
-
/>
|
|
40
|
-
))}
|
|
41
|
-
</svg>
|
|
42
|
-
);
|
|
43
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { BrainDepth, KnowledgeConcept, KnowledgeGraphModel, MemoryFragment, RelationshipThread } from "./types";
|
|
2
|
-
import { BrainGraphLayer, BrainKnowledgeLayer } from "./BrainGraphLayer";
|
|
3
|
-
import { BrainMemoryLayer } from "./BrainMemoryLayer";
|
|
4
|
-
import { BrainRelationshipLayer } from "./BrainRelationshipLayer";
|
|
5
|
-
|
|
6
|
-
export function DepthEmergence({
|
|
7
|
-
depth,
|
|
8
|
-
memories,
|
|
9
|
-
concepts,
|
|
10
|
-
relationships,
|
|
11
|
-
graphModel,
|
|
12
|
-
graphSearch,
|
|
13
|
-
selectedGraphId,
|
|
14
|
-
onGraphSearch,
|
|
15
|
-
onSelectGraphNode,
|
|
16
|
-
onRecallMemory,
|
|
17
|
-
}: {
|
|
18
|
-
depth: BrainDepth;
|
|
19
|
-
memories: MemoryFragment[];
|
|
20
|
-
concepts: KnowledgeConcept[];
|
|
21
|
-
relationships: RelationshipThread[];
|
|
22
|
-
graphModel: KnowledgeGraphModel;
|
|
23
|
-
graphSearch: string;
|
|
24
|
-
selectedGraphId: string | null;
|
|
25
|
-
onGraphSearch: (value: string) => void;
|
|
26
|
-
onSelectGraphNode: (id: string | null) => void;
|
|
27
|
-
onRecallMemory: (fragment: MemoryFragment) => void;
|
|
28
|
-
}) {
|
|
29
|
-
if (depth === 1) return null;
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<>
|
|
33
|
-
{depth >= 2 ? (
|
|
34
|
-
<BrainMemoryLayer memories={memories} depth={depth} onRecallMemory={onRecallMemory} />
|
|
35
|
-
) : null}
|
|
36
|
-
{depth >= 3 && depth < 5 ? (
|
|
37
|
-
<BrainKnowledgeLayer concepts={concepts} depth={depth} />
|
|
38
|
-
) : null}
|
|
39
|
-
{depth >= 4 && depth < 5 ? (
|
|
40
|
-
<BrainRelationshipLayer concepts={concepts} relationships={relationships} />
|
|
41
|
-
) : null}
|
|
42
|
-
{depth >= 5 ? (
|
|
43
|
-
<BrainGraphLayer
|
|
44
|
-
model={graphModel}
|
|
45
|
-
search={graphSearch}
|
|
46
|
-
selectedId={selectedGraphId}
|
|
47
|
-
onSearch={onGraphSearch}
|
|
48
|
-
onSelect={onSelectGraphNode}
|
|
49
|
-
/>
|
|
50
|
-
) : null}
|
|
51
|
-
</>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { asArray } from "@/lib/utils";
|
|
2
|
-
import type { ApiRecord, BrainDepth, BrainProof, BrainReadiness, KnowledgeConcept, KnowledgeGraphModel, MemoryFragment, RelationshipThread } from "./types";
|
|
3
|
-
import { clamp } from "./graphLayout";
|
|
4
|
-
|
|
5
|
-
export function buildMemoryFragments(memoryData: unknown, historyData: unknown): MemoryFragment[] {
|
|
6
|
-
const memory = isRecord(memoryData) ? memoryData : {};
|
|
7
|
-
const sourceRows = asArray<ApiRecord>(memory.sources).length
|
|
8
|
-
? asArray<ApiRecord>(memory.sources)
|
|
9
|
-
: asArray<ApiRecord>(memory.tiers);
|
|
10
|
-
const sourceFragments = sourceRows.map((item, index) => ({
|
|
11
|
-
id: textValue(item, ["id", "source", "label"], `memory-${index}`),
|
|
12
|
-
title: textValue(item, ["title", "label", "source", "path", "name"], "Workspace memory"),
|
|
13
|
-
kind: titleValue(item, ["type", "source_type", "kind", "health"], "Memory"),
|
|
14
|
-
}));
|
|
15
|
-
const conversationFragments = asArray<ApiRecord>(historyData).map((item, index) => ({
|
|
16
|
-
id: textValue(item, ["id", "conversation_id"], `conversation-${index}`),
|
|
17
|
-
title: textValue(item, ["title", "summary", "id"], "Conversation"),
|
|
18
|
-
kind: "Conversation",
|
|
19
|
-
}));
|
|
20
|
-
|
|
21
|
-
return uniqueById([...sourceFragments, ...conversationFragments]).slice(0, 10);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function parseKnowledgeGraph(data: unknown): KnowledgeGraphModel {
|
|
25
|
-
const graph = isRecord(data) ? data : {};
|
|
26
|
-
const rawNodes = asArray<ApiRecord>(graph.nodes);
|
|
27
|
-
const rawEdges = asArray<ApiRecord>(graph.edges);
|
|
28
|
-
const nodes = rawNodes.flatMap((node): KnowledgeConcept[] => {
|
|
29
|
-
const id = textValue(node, ["id", "node_id", "title", "label"]);
|
|
30
|
-
if (!id) return [];
|
|
31
|
-
const metadata = isRecord(node.metadata) ? node.metadata : {};
|
|
32
|
-
const type = titleValue(node, ["type", "kind", "category"], "Concept");
|
|
33
|
-
const label = textValue(node, ["title", "label", "name"], id.replace(/^[^:]+:/, ""));
|
|
34
|
-
const summary = textValue(node, ["summary", "description", "snippet"]) || textValue(metadata, ["summary", "description", "relative_path", "filename"]);
|
|
35
|
-
const importance = clamp(numberValue(node, ["importance_norm", "importance", "score"]) || 0.5, 0.08, 1);
|
|
36
|
-
const createdAt = timestampValue(node, ["created_at", "createdAt", "added_at", "addedAt", "timestamp", "updated_at", "updatedAt"])
|
|
37
|
-
?? timestampValue(metadata, ["created_at", "createdAt", "added_at", "addedAt", "timestamp", "updated_at", "updatedAt"]);
|
|
38
|
-
return [{ id, label, type, summary, importance, ...(createdAt !== undefined ? { createdAt } : {}) }];
|
|
39
|
-
}).sort((left, right) => right.importance - left.importance);
|
|
40
|
-
const ids = new Set(nodes.map((node) => node.id));
|
|
41
|
-
const edges = rawEdges.flatMap((edge, index): RelationshipThread[] => {
|
|
42
|
-
const source = textValue(edge, ["from", "source", "source_id"]);
|
|
43
|
-
const target = textValue(edge, ["to", "target", "target_id"]);
|
|
44
|
-
if (!source || !target || !ids.has(source) || !ids.has(target)) return [];
|
|
45
|
-
return [{
|
|
46
|
-
id: textValue(edge, ["id"], `edge-${index}`),
|
|
47
|
-
source,
|
|
48
|
-
target,
|
|
49
|
-
label: titleValue(edge, ["type", "label", "relationship"], "Relates"),
|
|
50
|
-
weight: numberValue(edge, ["weight", "score", "confidence"]) || 1,
|
|
51
|
-
}];
|
|
52
|
-
});
|
|
53
|
-
return { nodes, edges };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function currentModelName(data: unknown) {
|
|
57
|
-
const record = isRecord(data) ? data : {};
|
|
58
|
-
const current = textValue(record, ["current", "current_model", "local_model"]);
|
|
59
|
-
if (current) return current;
|
|
60
|
-
const loaded = asArray<ApiRecord>(record.loaded || record.loaded_models);
|
|
61
|
-
const firstLoaded = loaded.find((item) => item.id || item.name || item.model_id);
|
|
62
|
-
return firstLoaded ? textValue(firstLoaded, ["name", "id", "model_id"], "local mind") : "local mind";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function buildBrainReadiness(memoryData: unknown, fallbackMemoryCount: number, fallbackConceptCount: number): BrainReadiness {
|
|
66
|
-
const memory = isRecord(memoryData) ? memoryData : {};
|
|
67
|
-
const backend = isRecord(memory.brain_readiness) ? memory.brain_readiness : {};
|
|
68
|
-
const backendState = textValue(backend, ["state"]);
|
|
69
|
-
const backendDepth = numberValue(backend, ["depth"]);
|
|
70
|
-
const backendScore = numberValue(backend, ["score"]);
|
|
71
|
-
if ((backendState === "quiet" || backendState === "forming" || backendState === "alive") && isBrainDepth(backendDepth)) {
|
|
72
|
-
const signals = isRecord(backend.signals) ? backend.signals : {};
|
|
73
|
-
return {
|
|
74
|
-
score: clamp(Math.round(backendScore || 0), 0, 100),
|
|
75
|
-
state: backendState,
|
|
76
|
-
depth: backendDepth,
|
|
77
|
-
titleKey: textValue(backend, ["title_key", "titleKey"], `brain.readiness.${backendState}`),
|
|
78
|
-
actionKey: textValue(backend, ["action_key", "actionKey"], readinessActionKey(backendState)),
|
|
79
|
-
source: "memory_service",
|
|
80
|
-
signals: {
|
|
81
|
-
memoryCount: numberValue(signals, ["memory_count", "memoryCount"]),
|
|
82
|
-
conceptCount: numberValue(signals, ["concept_count", "conceptCount"]),
|
|
83
|
-
relationshipCount: numberValue(signals, ["relationship_count", "relationshipCount"]),
|
|
84
|
-
healthySources: numberValue(signals, ["healthy_sources", "healthySources"]),
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
return fallbackBrainReadiness(fallbackMemoryCount, fallbackConceptCount);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function buildBrainProof(data: unknown, fallbackModelName = ""): BrainProof {
|
|
92
|
-
const proof = isRecord(data) ? data : {};
|
|
93
|
-
const modelContinuity = isRecord(proof.model_continuity) ? proof.model_continuity : {};
|
|
94
|
-
const proofs = isRecord(proof.proofs) ? proof.proofs : {};
|
|
95
|
-
const recall = isRecord(proof.recall) ? proof.recall : {};
|
|
96
|
-
const claims = isRecord(proof.claims) ? proof.claims : {};
|
|
97
|
-
const durableItems = numberValue(proofs, ["durable_items", "durableItems"]);
|
|
98
|
-
return {
|
|
99
|
-
status: textValue(proof, ["status"], "quiet"),
|
|
100
|
-
modelContinuity: {
|
|
101
|
-
activeModel: textValue(modelContinuity, ["active_model", "activeModel"], fallbackModelName),
|
|
102
|
-
brainOwner: textValue(modelContinuity, ["brain_owner", "brainOwner"], "lattice_brain"),
|
|
103
|
-
capability: booleanValue(modelContinuity, ["capability"], true),
|
|
104
|
-
survivesModelSwitch: booleanValue(modelContinuity, ["survives_model_switch", "survivesModelSwitch"], false),
|
|
105
|
-
proven: booleanValue(modelContinuity, ["proven"], false),
|
|
106
|
-
contextStore: textValue(modelContinuity, ["context_store", "contextStore"], "workspace + conversation + graph + vector"),
|
|
107
|
-
},
|
|
108
|
-
proofs: {
|
|
109
|
-
durableItems,
|
|
110
|
-
hasDurableEvidence: booleanValue(proofs, ["has_durable_evidence", "hasDurableEvidence"], durableItems > 0),
|
|
111
|
-
workspaceMemories: numberValue(proofs, ["workspace_memories", "workspaceMemories"]),
|
|
112
|
-
conversations: numberValue(proofs, ["conversations"]),
|
|
113
|
-
graphConcepts: numberValue(proofs, ["graph_concepts", "graphConcepts"]),
|
|
114
|
-
vectorItems: numberValue(proofs, ["vector_items", "vectorItems"]),
|
|
115
|
-
healthySources: numberValue(proofs, ["healthy_sources", "healthySources"]),
|
|
116
|
-
},
|
|
117
|
-
recall: {
|
|
118
|
-
query: textValue(recall, ["query"]),
|
|
119
|
-
count: numberValue(recall, ["count"]),
|
|
120
|
-
items: asArray<ApiRecord>(recall.items).map((item, index) => ({
|
|
121
|
-
id: textValue(item, ["id"], `recall-${index}`),
|
|
122
|
-
source: titleValue(item, ["source"], "Memory"),
|
|
123
|
-
title: textValue(item, ["title"], "Memory"),
|
|
124
|
-
snippet: textValue(item, ["snippet"]),
|
|
125
|
-
score: numberValue(item, ["score"]),
|
|
126
|
-
})),
|
|
127
|
-
},
|
|
128
|
-
claims: {
|
|
129
|
-
canRecallUserContext: booleanValue(claims, ["can_recall_user_context", "canRecallUserContext"], false),
|
|
130
|
-
keepsContextAcrossModels: booleanValue(claims, ["keeps_context_across_models", "keepsContextAcrossModels"], false),
|
|
131
|
-
isKnowledgeStore: booleanValue(claims, ["is_knowledge_store", "isKnowledgeStore"], false),
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function uniqueById<T extends { id: string }>(items: T[]) {
|
|
137
|
-
const seen = new Set<string>();
|
|
138
|
-
return items.filter((item) => {
|
|
139
|
-
if (seen.has(item.id)) return false;
|
|
140
|
-
seen.add(item.id);
|
|
141
|
-
return true;
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function fallbackBrainReadiness(memoryCount: number, conceptCount: number): BrainReadiness {
|
|
146
|
-
const score = Math.min(100, Math.round(memoryCount * 12 + conceptCount * 10));
|
|
147
|
-
if (memoryCount < 1) {
|
|
148
|
-
return {
|
|
149
|
-
score: Math.max(12, score),
|
|
150
|
-
state: "quiet",
|
|
151
|
-
depth: 2,
|
|
152
|
-
titleKey: "brain.readiness.quiet",
|
|
153
|
-
actionKey: "brain.readiness.start",
|
|
154
|
-
source: "frontend_fallback",
|
|
155
|
-
signals: { memoryCount, conceptCount, relationshipCount: 0, healthySources: 0 },
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
if (conceptCount < 3) {
|
|
159
|
-
return {
|
|
160
|
-
score: Math.max(38, score),
|
|
161
|
-
state: "forming",
|
|
162
|
-
depth: 3,
|
|
163
|
-
titleKey: "brain.readiness.forming",
|
|
164
|
-
actionKey: "brain.readiness.grow",
|
|
165
|
-
source: "frontend_fallback",
|
|
166
|
-
signals: { memoryCount, conceptCount, relationshipCount: 0, healthySources: 0 },
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
return {
|
|
170
|
-
score: Math.max(72, score),
|
|
171
|
-
state: "alive",
|
|
172
|
-
depth: 5,
|
|
173
|
-
titleKey: "brain.readiness.alive",
|
|
174
|
-
actionKey: "brain.readiness.map",
|
|
175
|
-
source: "frontend_fallback",
|
|
176
|
-
signals: { memoryCount, conceptCount, relationshipCount: 0, healthySources: 0 },
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function readinessActionKey(state: "quiet" | "forming" | "alive") {
|
|
181
|
-
if (state === "quiet") return "brain.readiness.start";
|
|
182
|
-
if (state === "forming") return "brain.readiness.grow";
|
|
183
|
-
return "brain.readiness.map";
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function isBrainDepth(value: number): value is BrainDepth {
|
|
187
|
-
return value >= 1 && value <= 5 && Number.isInteger(value);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export function isRecord(value: unknown): value is ApiRecord {
|
|
191
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function textValue(record: ApiRecord, keys: string[], fallback = "") {
|
|
195
|
-
for (const key of keys) {
|
|
196
|
-
const value = record[key];
|
|
197
|
-
if (typeof value === "string" && value.trim()) return value;
|
|
198
|
-
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
199
|
-
}
|
|
200
|
-
return fallback;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function titleValue(record: ApiRecord, keys: string[], fallback = "") {
|
|
204
|
-
const value = textValue(record, keys, fallback);
|
|
205
|
-
return value
|
|
206
|
-
.replace(/[_-]+/g, " ")
|
|
207
|
-
.replace(/\b\w/g, (character) => character.toUpperCase());
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Parse a created/added timestamp into unix epoch milliseconds. Accepts ISO 8601
|
|
211
|
-
// strings, unix seconds, or unix milliseconds. Returns undefined when absent or
|
|
212
|
-
// unparseable so the time-exploration UI can fall back gracefully.
|
|
213
|
-
function timestampValue(record: ApiRecord, keys: string[]): number | undefined {
|
|
214
|
-
for (const key of keys) {
|
|
215
|
-
const value = record[key];
|
|
216
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
217
|
-
// Heuristic: values below ~1e12 are seconds, otherwise milliseconds.
|
|
218
|
-
return value < 1e12 ? value * 1000 : value;
|
|
219
|
-
}
|
|
220
|
-
if (typeof value === "string" && value.trim()) {
|
|
221
|
-
const numeric = Number(value);
|
|
222
|
-
if (Number.isFinite(numeric) && /^\d+$/.test(value.trim())) {
|
|
223
|
-
return numeric < 1e12 ? numeric * 1000 : numeric;
|
|
224
|
-
}
|
|
225
|
-
const parsed = Date.parse(value);
|
|
226
|
-
if (Number.isFinite(parsed)) return parsed;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return undefined;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function numberValue(record: ApiRecord, keys: string[]) {
|
|
233
|
-
for (const key of keys) {
|
|
234
|
-
const value = Number(record[key]);
|
|
235
|
-
if (Number.isFinite(value)) return value;
|
|
236
|
-
}
|
|
237
|
-
return 0;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function booleanValue(record: ApiRecord, keys: string[], fallback: boolean) {
|
|
241
|
-
for (const key of keys) {
|
|
242
|
-
const value = record[key];
|
|
243
|
-
if (typeof value === "boolean") return value;
|
|
244
|
-
}
|
|
245
|
-
return fallback;
|
|
246
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import type { KnowledgeConcept, RelationshipThread } from "./types";
|
|
3
|
-
|
|
4
|
-
// Return the set of node ids that share a direct (1-hop) edge with `nodeId`.
|
|
5
|
-
// The focused node itself is not included.
|
|
6
|
-
export function computeGraphNeighbors(nodeId: string, edges: RelationshipThread[]): Set<string> {
|
|
7
|
-
const neighbors = new Set<string>();
|
|
8
|
-
for (const edge of edges) {
|
|
9
|
-
if (edge.source === nodeId) neighbors.add(edge.target);
|
|
10
|
-
else if (edge.target === nodeId) neighbors.add(edge.source);
|
|
11
|
-
}
|
|
12
|
-
return neighbors;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function layoutGraphNodes(nodes: KnowledgeConcept[], radiusX: number, radiusY: number) {
|
|
16
|
-
return nodes.map((node, index) => {
|
|
17
|
-
const point = polarPoint(index, nodes.length, radiusX, radiusY, -88);
|
|
18
|
-
return { node, x: point.x, y: point.y };
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function polarPoint(index: number, total: number, radiusX: number, radiusY: number, offsetDegrees = -90) {
|
|
23
|
-
const count = Math.max(total, 1);
|
|
24
|
-
const angle = ((360 / count) * index + offsetDegrees) * Math.PI / 180;
|
|
25
|
-
return {
|
|
26
|
-
x: 50 + Math.cos(angle) * radiusX,
|
|
27
|
-
y: 50 + Math.sin(angle) * radiusY,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function layerStyle(values: Record<string, string>) {
|
|
32
|
-
return values as React.CSSProperties;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function clamp(value: number, min: number, max: number) {
|
|
36
|
-
return Math.max(min, Math.min(max, value));
|
|
37
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { BrainState } from "@/components/LivingBrain";
|
|
2
|
-
|
|
3
|
-
export type ApiRecord = Record<string, unknown>;
|
|
4
|
-
export type BrainDepth = 1 | 2 | 3 | 4 | 5;
|
|
5
|
-
|
|
6
|
-
export type Message = {
|
|
7
|
-
role: "user" | "assistant";
|
|
8
|
-
content: string;
|
|
9
|
-
proof?: MessageProof;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export type MessageProof = {
|
|
13
|
-
query: string;
|
|
14
|
-
model: string;
|
|
15
|
-
provenAcrossModels: boolean;
|
|
16
|
-
citations: Array<{
|
|
17
|
-
id: string;
|
|
18
|
-
source: string;
|
|
19
|
-
title: string;
|
|
20
|
-
snippet: string;
|
|
21
|
-
}>;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type MemoryFragment = {
|
|
25
|
-
id: string;
|
|
26
|
-
title: string;
|
|
27
|
-
kind: string;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export type KnowledgeConcept = {
|
|
31
|
-
id: string;
|
|
32
|
-
label: string;
|
|
33
|
-
type: string;
|
|
34
|
-
summary: string;
|
|
35
|
-
importance: number;
|
|
36
|
-
// Optional unix epoch (ms) the concept was added to the graph. Enables
|
|
37
|
-
// time-based exploration; absent when the backend does not yet emit it.
|
|
38
|
-
createdAt?: number;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export type RelationshipThread = {
|
|
42
|
-
id: string;
|
|
43
|
-
source: string;
|
|
44
|
-
target: string;
|
|
45
|
-
label: string;
|
|
46
|
-
weight: number;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export type KnowledgeGraphModel = {
|
|
50
|
-
nodes: KnowledgeConcept[];
|
|
51
|
-
edges: RelationshipThread[];
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export type BrainReadiness = {
|
|
55
|
-
score: number;
|
|
56
|
-
state: "quiet" | "forming" | "alive";
|
|
57
|
-
depth: BrainDepth;
|
|
58
|
-
titleKey: string;
|
|
59
|
-
actionKey: string;
|
|
60
|
-
source: "memory_service" | "frontend_fallback";
|
|
61
|
-
signals: {
|
|
62
|
-
memoryCount: number;
|
|
63
|
-
conceptCount: number;
|
|
64
|
-
relationshipCount: number;
|
|
65
|
-
healthySources: number;
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export type BrainProof = {
|
|
70
|
-
status: "quiet" | "forming" | "alive" | string;
|
|
71
|
-
modelContinuity: {
|
|
72
|
-
activeModel: string;
|
|
73
|
-
brainOwner: string;
|
|
74
|
-
capability: boolean;
|
|
75
|
-
survivesModelSwitch: boolean;
|
|
76
|
-
proven: boolean;
|
|
77
|
-
contextStore: string;
|
|
78
|
-
};
|
|
79
|
-
proofs: {
|
|
80
|
-
durableItems: number;
|
|
81
|
-
hasDurableEvidence: boolean;
|
|
82
|
-
workspaceMemories: number;
|
|
83
|
-
conversations: number;
|
|
84
|
-
graphConcepts: number;
|
|
85
|
-
vectorItems: number;
|
|
86
|
-
healthySources: number;
|
|
87
|
-
};
|
|
88
|
-
recall: {
|
|
89
|
-
query: string;
|
|
90
|
-
count: number;
|
|
91
|
-
items: Array<{
|
|
92
|
-
id: string;
|
|
93
|
-
source: string;
|
|
94
|
-
title: string;
|
|
95
|
-
snippet: string;
|
|
96
|
-
score: number;
|
|
97
|
-
}>;
|
|
98
|
-
};
|
|
99
|
-
claims: {
|
|
100
|
-
canRecallUserContext: boolean;
|
|
101
|
-
keepsContextAcrossModels: boolean;
|
|
102
|
-
isKnowledgeStore: boolean;
|
|
103
|
-
};
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
export type IngestionSourceType = "file" | "folder" | "note" | "web";
|
|
107
|
-
|
|
108
|
-
export type IngestionPipelineStage =
|
|
109
|
-
| "preparing"
|
|
110
|
-
| "parsing"
|
|
111
|
-
| "embedding"
|
|
112
|
-
| "indexing"
|
|
113
|
-
| "complete"
|
|
114
|
-
| "error";
|
|
115
|
-
|
|
116
|
-
export type IngestionState = {
|
|
117
|
-
sourceType: IngestionSourceType;
|
|
118
|
-
label: string;
|
|
119
|
-
stage: IngestionPipelineStage;
|
|
120
|
-
startedAt: number;
|
|
121
|
-
completedAt: number | null;
|
|
122
|
-
newMemories: number;
|
|
123
|
-
newEntities: number;
|
|
124
|
-
error?: string;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export type EmergenceEvent = {
|
|
128
|
-
id: string;
|
|
129
|
-
sourceType: IngestionSourceType;
|
|
130
|
-
label: string;
|
|
131
|
-
newMemories: number;
|
|
132
|
-
newEntities: number;
|
|
133
|
-
at: number;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export const INGESTION_STAGE_ORDER: IngestionPipelineStage[] = [
|
|
137
|
-
"preparing",
|
|
138
|
-
"parsing",
|
|
139
|
-
"embedding",
|
|
140
|
-
"indexing",
|
|
141
|
-
"complete",
|
|
142
|
-
];
|
|
143
|
-
|
|
144
|
-
export const DEPTHS: Array<{ level: BrainDepth; labelKey: string; state: BrainState }> = [
|
|
145
|
-
{ level: 1, labelKey: "brain.depthLabel.1", state: "idle" },
|
|
146
|
-
{ level: 2, labelKey: "brain.depthLabel.2", state: "recalling" },
|
|
147
|
-
{ level: 3, labelKey: "brain.depthLabel.3", state: "synthesizing" },
|
|
148
|
-
{ level: 4, labelKey: "brain.depthLabel.4", state: "planning" },
|
|
149
|
-
{ level: 5, labelKey: "brain.depthLabel.5", state: "synthesizing" },
|
|
150
|
-
];
|