@ltm-blueverse/alpha-semantic-hub 0.7.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/LICENSE +21 -0
- package/README.md +1674 -0
- package/explorer/README.md +282 -0
- package/explorer/src/App.css +0 -0
- package/explorer/src/App.tsx +2035 -0
- package/explorer/src/ErrorBoundary.tsx +112 -0
- package/explorer/src/ExploreWorkspaceTabs.tsx +29 -0
- package/explorer/src/assets/hero.png +0 -0
- package/explorer/src/assets/react.svg +1 -0
- package/explorer/src/assets/vite.svg +1 -0
- package/explorer/src/explorerCapabilities.ts +24 -0
- package/explorer/src/index.css +71 -0
- package/explorer/src/main.tsx +7 -0
- package/explorer/src/store/edgePairKeys.d.ts +2 -0
- package/explorer/src/store/edgePairKeys.js +7 -0
- package/explorer/src/store/graphStore.ts +183 -0
- package/explorer/src/store/registryStore.ts +78 -0
- package/explorer/src/types.d.ts +16 -0
- package/explorer/src/ui/primitives.css +414 -0
- package/explorer/src/ui/primitives.tsx +170 -0
- package/explorer/src/workspaces/DecisionWorkspace/DecisionWorkspace.tsx +279 -0
- package/explorer/src/workspaces/DiffMergeWorkspace/DiffMergeWorkspace.tsx +121 -0
- package/explorer/src/workspaces/EnrichWorkspace/EntityResolutionTab.tsx +454 -0
- package/explorer/src/workspaces/EnrichWorkspace/RegistryTab.tsx +285 -0
- package/explorer/src/workspaces/GraphWorkspace/GraphCanvas.tsx +2673 -0
- package/explorer/src/workspaces/GraphWorkspace/GraphInspectorPanel.tsx +771 -0
- package/explorer/src/workspaces/GraphWorkspace/GraphLoadingOverlay.tsx +410 -0
- package/explorer/src/workspaces/GraphWorkspace/GraphWorkspace.tsx +3584 -0
- package/explorer/src/workspaces/GraphWorkspace/MarkdownContentViewer.tsx +705 -0
- package/explorer/src/workspaces/GraphWorkspace/SigmaSceneAdapter.tsx +55 -0
- package/explorer/src/workspaces/GraphWorkspace/TimelinePanel.tsx +193 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/clickSelectionBehavior.ts +29 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/fitViewBehavior.ts +15 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/focusCameraBehavior.ts +25 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/hoverActivationBehavior.ts +15 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/pathHighlightBehavior.ts +52 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/searchFocusBehavior.ts +36 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/types.ts +41 -0
- package/explorer/src/workspaces/GraphWorkspace/behaviors/viewModeSwitchBehavior.ts +29 -0
- package/explorer/src/workspaces/GraphWorkspace/graphAnalytics.ts +779 -0
- package/explorer/src/workspaces/GraphWorkspace/graphColorLegend.ts +36 -0
- package/explorer/src/workspaces/GraphWorkspace/graphConfig.ts +102 -0
- package/explorer/src/workspaces/GraphWorkspace/graphEntityShape.ts +34 -0
- package/explorer/src/workspaces/GraphWorkspace/graphLoading.ts +84 -0
- package/explorer/src/workspaces/GraphWorkspace/graphSceneLayers.ts +775 -0
- package/explorer/src/workspaces/GraphWorkspace/graphSceneState.ts +2753 -0
- package/explorer/src/workspaces/GraphWorkspace/graphStructureLayer.ts +335 -0
- package/explorer/src/workspaces/GraphWorkspace/graphTheme.ts +1078 -0
- package/explorer/src/workspaces/GraphWorkspace/graphViewCopy.ts +41 -0
- package/explorer/src/workspaces/GraphWorkspace/localGraphTransition.ts +9 -0
- package/explorer/src/workspaces/GraphWorkspace/markdownEditorState.ts +114 -0
- package/explorer/src/workspaces/GraphWorkspace/markdownResourceClient.ts +103 -0
- package/explorer/src/workspaces/GraphWorkspace/markdownUrlSafety.ts +29 -0
- package/explorer/src/workspaces/GraphWorkspace/nodeMarkdownSync.ts +81 -0
- package/explorer/src/workspaces/GraphWorkspace/pluginRegistryPredicates.ts +24 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPlugin.tsx +353 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPluginPhaseC.tsx +522 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/index.ts +16 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/legendPlugin.tsx +120 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/neighborhoodPanelPlugin.tsx +231 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/temporalOverlayPlugin.tsx +142 -0
- package/explorer/src/workspaces/GraphWorkspace/plugins/types.ts +106 -0
- package/explorer/src/workspaces/GraphWorkspace/realtimeGraphAttributes.ts +50 -0
- package/explorer/src/workspaces/GraphWorkspace/scene.ts +79 -0
- package/explorer/src/workspaces/GraphWorkspace/sigmaNativeRendering.ts +421 -0
- package/explorer/src/workspaces/GraphWorkspace/smallGraphLayout.ts +135 -0
- package/explorer/src/workspaces/GraphWorkspace/temporalLifecyclePredicates.ts +31 -0
- package/explorer/src/workspaces/GraphWorkspace/temporalScrubberBounds.ts +46 -0
- package/explorer/src/workspaces/GraphWorkspace/temporalSnapshotGuards.ts +113 -0
- package/explorer/src/workspaces/GraphWorkspace/types.ts +395 -0
- package/explorer/src/workspaces/GraphWorkspace/useLoadGraph.ts +746 -0
- package/explorer/src/workspaces/GraphWorkspace/useMarkdownEditor.ts +177 -0
- package/explorer/src/workspaces/ImportExportWorkspace/ImportExportWorkspace.tsx +196 -0
- package/explorer/src/workspaces/LineageWorkspace/LineageDiagram.tsx +177 -0
- package/explorer/src/workspaces/ManageWorkspace/KGOverviewTab.tsx +291 -0
- package/explorer/src/workspaces/ManageWorkspace/OntologySummaryTab.tsx +346 -0
- package/explorer/src/workspaces/MemoryWorkspace.tsx +464 -0
- package/explorer/src/workspaces/OntologyWorkspace/AlignmentsTab.tsx +437 -0
- package/explorer/src/workspaces/OntologyWorkspace/HealthTab.tsx +214 -0
- package/explorer/src/workspaces/OntologyWorkspace/OntologyEditor.tsx +770 -0
- package/explorer/src/workspaces/OntologyWorkspace/OntologyLoader.tsx +913 -0
- package/explorer/src/workspaces/OntologyWorkspace/OntologyManager.tsx +930 -0
- package/explorer/src/workspaces/OntologyWorkspace/OntologySearch.tsx +590 -0
- package/explorer/src/workspaces/OntologyWorkspace/ProposalReview.tsx +429 -0
- package/explorer/src/workspaces/OntologyWorkspace/SKOSVocabularyManager.tsx +696 -0
- package/explorer/src/workspaces/OntologyWorkspace/ShaclStudio.tsx +363 -0
- package/explorer/src/workspaces/OntologyWorkspace/VersionsTab.tsx +546 -0
- package/explorer/src/workspaces/OntologyWorkspace/api.ts +164 -0
- package/explorer/src/workspaces/OntologyWorkspace/index.tsx +101 -0
- package/explorer/src/workspaces/OntologyWorkspace/ontologyEditorModel.ts +87 -0
- package/explorer/src/workspaces/OntologyWorkspace/ontologyUrlState.ts +94 -0
- package/explorer/src/workspaces/OntologyWorkspace/types.ts +119 -0
- package/explorer/src/workspaces/ReasoningWorkspace.tsx +243 -0
- package/explorer/src/workspaces/SparqlWorkspace/SparqlWorkspace.tsx +271 -0
- package/explorer/src/workspaces/VocabularyWorkspace/ConceptTree.tsx +97 -0
- package/explorer/src/workspaces/VocabularyWorkspace/ImportDropzone.tsx +95 -0
- package/explorer/src/workspaces/VocabularyWorkspace/PropertyPanel.tsx +116 -0
- package/explorer/src/workspaces/VocabularyWorkspace/Sidebar.tsx +112 -0
- package/explorer/src/workspaces/VocabularyWorkspace/VocabularyWorkspace.tsx +70 -0
- package/explorer/src/workspaces/VocabularyWorkspace/queries.ts +52 -0
- package/explorer/src/workspaces/VocabularyWorkspace/types.ts +24 -0
- package/package.json +31 -0
- package/plugins/.claude-plugin/README.md +262 -0
- package/plugins/.claude-plugin/marketplace.json +20 -0
- package/plugins/.claude-plugin/plugin.json +33 -0
- package/plugins/.cline-plugin/README.md +32 -0
- package/plugins/.cline-plugin/marketplace.json +17 -0
- package/plugins/.cline-plugin/plugin.json +35 -0
- package/plugins/.codex-plugin/marketplace.json +21 -0
- package/plugins/.codex-plugin/plugin.json +35 -0
- package/plugins/.continue-plugin/README.md +34 -0
- package/plugins/.continue-plugin/marketplace.json +17 -0
- package/plugins/.continue-plugin/plugin.json +33 -0
- package/plugins/.cursor-plugin/marketplace.json +18 -0
- package/plugins/.cursor-plugin/plugin.json +32 -0
- package/plugins/.openclaw-plugin/README.md +62 -0
- package/plugins/.openclaw-plugin/marketplace.json +18 -0
- package/plugins/.openclaw-plugin/plugin.json +46 -0
- package/plugins/.pi-plugin/README.md +35 -0
- package/plugins/.vscode-plugin/README.md +48 -0
- package/plugins/.vscode-plugin/marketplace.json +17 -0
- package/plugins/.vscode-plugin/plugin.json +35 -0
- package/plugins/.windsurf-plugin/README.md +39 -0
- package/plugins/.windsurf-plugin/marketplace.json +17 -0
- package/plugins/.windsurf-plugin/plugin.json +35 -0
- package/plugins/agents/decision-advisor.md +126 -0
- package/plugins/agents/explainability.md +129 -0
- package/plugins/agents/kg-assistant.md +73 -0
- package/plugins/hooks/hooks.json +12 -0
- package/plugins/skills/causal/SKILL.md +74 -0
- package/plugins/skills/change/SKILL.md +80 -0
- package/plugins/skills/decision/SKILL.md +197 -0
- package/plugins/skills/deduplicate/SKILL.md +41 -0
- package/plugins/skills/embed/SKILL.md +230 -0
- package/plugins/skills/explain/SKILL.md +44 -0
- package/plugins/skills/export/SKILL.md +67 -0
- package/plugins/skills/extract/SKILL.md +93 -0
- package/plugins/skills/ingest/SKILL.md +38 -0
- package/plugins/skills/ontology/SKILL.md +89 -0
- package/plugins/skills/policy/SKILL.md +66 -0
- package/plugins/skills/provenance/SKILL.md +70 -0
- package/plugins/skills/query/SKILL.md +84 -0
- package/plugins/skills/reason/SKILL.md +201 -0
- package/plugins/skills/temporal/SKILL.md +164 -0
- package/plugins/skills/validate/SKILL.md +228 -0
- package/plugins/skills/visualize/SKILL.md +249 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState, type CSSProperties } from "react";
|
|
2
|
+
import { Brain, RefreshCw } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
import { MarkdownContentViewer } from "./GraphWorkspace/MarkdownContentViewer";
|
|
5
|
+
import {
|
|
6
|
+
readMarkdownResource,
|
|
7
|
+
type MarkdownApplyResult,
|
|
8
|
+
} from "./GraphWorkspace/markdownResourceClient";
|
|
9
|
+
import { GRAPH_THEME } from "./GraphWorkspace/graphTheme";
|
|
10
|
+
|
|
11
|
+
interface MemorySummary {
|
|
12
|
+
id: string;
|
|
13
|
+
type: string;
|
|
14
|
+
excerpt: string;
|
|
15
|
+
updated_at: string | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface MemoryListResponse {
|
|
19
|
+
items: MemorySummary[];
|
|
20
|
+
total: number;
|
|
21
|
+
skip: number;
|
|
22
|
+
limit: number;
|
|
23
|
+
}
|
|
24
|
+
interface MemoryWorkspaceProps {
|
|
25
|
+
onDirtyChange?: (dirty: boolean) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const MEMORY_PAGE_SIZE = 100;
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
function responseMessage(payload: unknown, fallback: string): string {
|
|
32
|
+
if (!payload || typeof payload !== "object" || !("detail" in payload)) {
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
return typeof payload.detail === "string" ? payload.detail : fallback;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async function fetchMemoryList(skip = 0): Promise<MemoryListResponse> {
|
|
40
|
+
const response = await fetch(`/api/memories?skip=${skip}&limit=${MEMORY_PAGE_SIZE}`);
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const payload = await response.json().catch(() => null);
|
|
43
|
+
throw new Error(responseMessage(payload, `Memory list failed (${response.status}).`));
|
|
44
|
+
}
|
|
45
|
+
return response.json() as Promise<MemoryListResponse>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function fetchLoadedMemoryPages(endOffset: number): Promise<{
|
|
49
|
+
items: MemorySummary[];
|
|
50
|
+
total: number;
|
|
51
|
+
nextOffset: number;
|
|
52
|
+
}> {
|
|
53
|
+
const items: MemorySummary[] = [];
|
|
54
|
+
let total = 0;
|
|
55
|
+
let nextOffset = 0;
|
|
56
|
+
const targetOffset = Math.max(endOffset, MEMORY_PAGE_SIZE);
|
|
57
|
+
|
|
58
|
+
while (nextOffset < targetOffset) {
|
|
59
|
+
const payload = await fetchMemoryList(nextOffset);
|
|
60
|
+
items.push(...payload.items);
|
|
61
|
+
total = payload.total;
|
|
62
|
+
nextOffset = payload.skip + payload.items.length;
|
|
63
|
+
if (payload.items.length === 0 || nextOffset >= total) break;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { items, total, nextOffset };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function MemoryWorkspace({ onDirtyChange }: MemoryWorkspaceProps = {}) {
|
|
70
|
+
const [items, setItems] = useState<MemorySummary[]>([]);
|
|
71
|
+
const [total, setTotal] = useState(0);
|
|
72
|
+
const [nextOffset, setNextOffset] = useState(0);
|
|
73
|
+
const [selectedId, setSelectedId] = useState("");
|
|
74
|
+
const [selectedBody, setSelectedBody] = useState("");
|
|
75
|
+
const [loading, setLoading] = useState(true);
|
|
76
|
+
const [loadingMore, setLoadingMore] = useState(false);
|
|
77
|
+
const [error, setError] = useState("");
|
|
78
|
+
const [dirty, setDirty] = useState(false);
|
|
79
|
+
const [reloadToken, setReloadToken] = useState(0);
|
|
80
|
+
const listGenerationRef = useRef(0);
|
|
81
|
+
const selectionGenerationRef = useRef(0);
|
|
82
|
+
const handleDirtyChange = useCallback((nextDirty: boolean) => {
|
|
83
|
+
setDirty(nextDirty);
|
|
84
|
+
onDirtyChange?.(nextDirty);
|
|
85
|
+
}, [onDirtyChange]);
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
let cancelled = false;
|
|
90
|
+
const listGeneration = ++listGenerationRef.current;
|
|
91
|
+
const selectionGeneration = ++selectionGenerationRef.current;
|
|
92
|
+
const isCurrent = () => (
|
|
93
|
+
!cancelled
|
|
94
|
+
&& listGeneration === listGenerationRef.current
|
|
95
|
+
&& selectionGeneration === selectionGenerationRef.current
|
|
96
|
+
);
|
|
97
|
+
const load = async () => {
|
|
98
|
+
setLoading(true);
|
|
99
|
+
setLoadingMore(false);
|
|
100
|
+
setError("");
|
|
101
|
+
try {
|
|
102
|
+
const payload = await fetchMemoryList();
|
|
103
|
+
if (!isCurrent()) return;
|
|
104
|
+
setItems(payload.items);
|
|
105
|
+
setTotal(payload.total);
|
|
106
|
+
setNextOffset(payload.skip + payload.items.length);
|
|
107
|
+
const first = payload.items[0];
|
|
108
|
+
if (!first) {
|
|
109
|
+
setSelectedId("");
|
|
110
|
+
setSelectedBody("");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const document = await readMarkdownResource({
|
|
114
|
+
kind: "agent-memory",
|
|
115
|
+
id: first.id,
|
|
116
|
+
});
|
|
117
|
+
if (!isCurrent()) return;
|
|
118
|
+
setSelectedId(first.id);
|
|
119
|
+
setSelectedBody(document.body);
|
|
120
|
+
} catch (failure) {
|
|
121
|
+
if (isCurrent()) {
|
|
122
|
+
setError(failure instanceof Error ? failure.message : "Memories could not be loaded.");
|
|
123
|
+
}
|
|
124
|
+
} finally {
|
|
125
|
+
if (isCurrent()) setLoading(false);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
void load();
|
|
129
|
+
return () => {
|
|
130
|
+
cancelled = true;
|
|
131
|
+
listGenerationRef.current += 1;
|
|
132
|
+
selectionGenerationRef.current += 1;
|
|
133
|
+
};
|
|
134
|
+
}, [reloadToken]);
|
|
135
|
+
|
|
136
|
+
const selectMemory = async (memoryId: string) => {
|
|
137
|
+
if (memoryId === selectedId) return;
|
|
138
|
+
if (dirty && !window.confirm("Discard the unapplied Markdown draft and open another memory?")) return;
|
|
139
|
+
const selectionGeneration = ++selectionGenerationRef.current;
|
|
140
|
+
// Do NOT call handleDirtyChange(false) here: the editor's own onDirtyChange
|
|
141
|
+
// callback fires automatically when MarkdownContentViewer re-renders with
|
|
142
|
+
// the new resource prop and its session is cleared.
|
|
143
|
+
setLoading(true);
|
|
144
|
+
setError("");
|
|
145
|
+
try {
|
|
146
|
+
const document = await readMarkdownResource({
|
|
147
|
+
kind: "agent-memory",
|
|
148
|
+
id: memoryId,
|
|
149
|
+
});
|
|
150
|
+
if (selectionGeneration !== selectionGenerationRef.current) return;
|
|
151
|
+
setSelectedId(memoryId);
|
|
152
|
+
setSelectedBody(document.body);
|
|
153
|
+
} catch (failure) {
|
|
154
|
+
if (selectionGeneration === selectionGenerationRef.current) {
|
|
155
|
+
setError(failure instanceof Error ? failure.message : "The memory could not be loaded.");
|
|
156
|
+
}
|
|
157
|
+
} finally {
|
|
158
|
+
if (selectionGeneration === selectionGenerationRef.current) {
|
|
159
|
+
setLoading(false);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const loadMoreMemories = useCallback(async () => {
|
|
165
|
+
if (loadingMore || nextOffset >= total) return;
|
|
166
|
+
const listGeneration = ++listGenerationRef.current;
|
|
167
|
+
setLoadingMore(true);
|
|
168
|
+
setError("");
|
|
169
|
+
try {
|
|
170
|
+
const payload = await fetchMemoryList(nextOffset);
|
|
171
|
+
if (listGeneration !== listGenerationRef.current) return;
|
|
172
|
+
setItems((current) => {
|
|
173
|
+
const knownIds = new Set(current.map((item) => item.id));
|
|
174
|
+
return [
|
|
175
|
+
...current,
|
|
176
|
+
...payload.items.filter((item) => !knownIds.has(item.id)),
|
|
177
|
+
];
|
|
178
|
+
});
|
|
179
|
+
setTotal(payload.total);
|
|
180
|
+
setNextOffset(payload.skip + payload.items.length);
|
|
181
|
+
} catch (failure) {
|
|
182
|
+
if (listGeneration === listGenerationRef.current) {
|
|
183
|
+
setError(failure instanceof Error ? failure.message : "More memories could not be loaded.");
|
|
184
|
+
}
|
|
185
|
+
} finally {
|
|
186
|
+
if (listGeneration === listGenerationRef.current) {
|
|
187
|
+
setLoadingMore(false);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}, [loadingMore, nextOffset, total]);
|
|
191
|
+
|
|
192
|
+
const refreshMemorySummaries = useCallback(async () => {
|
|
193
|
+
const listGeneration = ++listGenerationRef.current;
|
|
194
|
+
try {
|
|
195
|
+
const payload = await fetchLoadedMemoryPages(nextOffset);
|
|
196
|
+
if (listGeneration !== listGenerationRef.current) return;
|
|
197
|
+
setItems(payload.items);
|
|
198
|
+
setTotal(payload.total);
|
|
199
|
+
setNextOffset(payload.nextOffset);
|
|
200
|
+
} catch {
|
|
201
|
+
if (listGeneration === listGenerationRef.current) {
|
|
202
|
+
setError("Memory was applied, but its summary could not be refreshed.");
|
|
203
|
+
}
|
|
204
|
+
} finally {
|
|
205
|
+
if (listGeneration === listGenerationRef.current) {
|
|
206
|
+
setLoadingMore(false);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}, [nextOffset]);
|
|
210
|
+
|
|
211
|
+
const applyMemory = useCallback((result: MarkdownApplyResult) => {
|
|
212
|
+
setSelectedBody(result.body);
|
|
213
|
+
handleDirtyChange(false);
|
|
214
|
+
setItems((current) => current.map((item) => (
|
|
215
|
+
item.id === result.resource.id
|
|
216
|
+
? { ...item, excerpt: result.body.replace(/\s+/g, " ").slice(0, 160) }
|
|
217
|
+
: item
|
|
218
|
+
)));
|
|
219
|
+
void refreshMemorySummaries();
|
|
220
|
+
}, [handleDirtyChange, refreshMemorySummaries]);
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
<div style={workspaceStyle}>
|
|
224
|
+
<aside style={listPanelStyle} aria-label="Agent memories">
|
|
225
|
+
<div style={listHeaderStyle}>
|
|
226
|
+
<div>
|
|
227
|
+
<div style={listTitleStyle}>AgentMemory</div>
|
|
228
|
+
<div style={listCountStyle}>{items.length} of {total} loaded</div>
|
|
229
|
+
</div>
|
|
230
|
+
<button
|
|
231
|
+
type="button"
|
|
232
|
+
aria-label="Refresh memories"
|
|
233
|
+
onClick={() => setReloadToken((value) => value + 1)}
|
|
234
|
+
disabled={loading || loadingMore || dirty}
|
|
235
|
+
title={dirty ? "Apply or cancel the current draft before refreshing" : "Refresh memories"}
|
|
236
|
+
style={{ ...iconButtonStyle, opacity: loading || loadingMore || dirty ? 0.55 : 1 }}
|
|
237
|
+
>
|
|
238
|
+
<RefreshCw size={14} aria-hidden="true" />
|
|
239
|
+
</button>
|
|
240
|
+
</div>
|
|
241
|
+
<div style={memoryListStyle}>
|
|
242
|
+
{items.map((item) => (
|
|
243
|
+
<button
|
|
244
|
+
type="button"
|
|
245
|
+
key={item.id}
|
|
246
|
+
onClick={() => void selectMemory(item.id)}
|
|
247
|
+
aria-current={item.id === selectedId ? "true" : undefined}
|
|
248
|
+
style={{
|
|
249
|
+
...memoryButtonStyle,
|
|
250
|
+
...(item.id === selectedId ? selectedMemoryButtonStyle : {}),
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
<span style={memoryTypeStyle}>{item.type}</span>
|
|
254
|
+
<span style={memoryIdStyle}>{item.id}</span>
|
|
255
|
+
<span style={memoryExcerptStyle}>{item.excerpt || "Empty memory"}</span>
|
|
256
|
+
</button>
|
|
257
|
+
))}
|
|
258
|
+
{nextOffset < total ? (
|
|
259
|
+
<button
|
|
260
|
+
type="button"
|
|
261
|
+
aria-label="Load more memories"
|
|
262
|
+
onClick={() => void loadMoreMemories()}
|
|
263
|
+
disabled={loading || loadingMore}
|
|
264
|
+
style={{ ...retryButtonStyle, opacity: loading || loadingMore ? 0.55 : 1 }}
|
|
265
|
+
>
|
|
266
|
+
{loadingMore ? "Loading…" : "Load more"}
|
|
267
|
+
</button>
|
|
268
|
+
) : null}
|
|
269
|
+
{!loading && items.length === 0 ? (
|
|
270
|
+
<div style={emptyStyle}>
|
|
271
|
+
<Brain size={22} aria-hidden="true" />
|
|
272
|
+
<span>No AgentMemory items are available.</span>
|
|
273
|
+
<button type="button" onClick={() => setReloadToken((value) => value + 1)} style={retryButtonStyle}>
|
|
274
|
+
Refresh
|
|
275
|
+
</button>
|
|
276
|
+
</div>
|
|
277
|
+
) : null}
|
|
278
|
+
</div>
|
|
279
|
+
</aside>
|
|
280
|
+
|
|
281
|
+
<main style={editorPanelStyle}>
|
|
282
|
+
{error ? <div role="alert" style={alertStyle}>{error}</div> : null}
|
|
283
|
+
{loading ? (
|
|
284
|
+
<div role="status" style={emptyStyle}>Loading memories…</div>
|
|
285
|
+
) : selectedId ? (
|
|
286
|
+
<>
|
|
287
|
+
<div style={selectionHeaderStyle}>
|
|
288
|
+
<span style={selectionLabelStyle}>Selected memory</span>
|
|
289
|
+
<strong style={selectionIdStyle}>{selectedId}</strong>
|
|
290
|
+
</div>
|
|
291
|
+
<MarkdownContentViewer
|
|
292
|
+
content={selectedBody}
|
|
293
|
+
resource={{ kind: "agent-memory", id: selectedId }}
|
|
294
|
+
onApplied={applyMemory}
|
|
295
|
+
onDirtyChange={handleDirtyChange}
|
|
296
|
+
/>
|
|
297
|
+
</>
|
|
298
|
+
) : null}
|
|
299
|
+
</main>
|
|
300
|
+
</div>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const workspaceStyle: CSSProperties = {
|
|
305
|
+
display: "grid",
|
|
306
|
+
gridTemplateColumns: "minmax(220px, 300px) minmax(0, 1fr)",
|
|
307
|
+
height: "100%",
|
|
308
|
+
minHeight: 0,
|
|
309
|
+
background: GRAPH_THEME.ui.surface.stage,
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const listPanelStyle: CSSProperties = {
|
|
313
|
+
display: "flex",
|
|
314
|
+
flexDirection: "column",
|
|
315
|
+
minHeight: 0,
|
|
316
|
+
borderRight: `1px solid ${GRAPH_THEME.ui.surface.panelBorder}`,
|
|
317
|
+
background: GRAPH_THEME.ui.surface.panel,
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const listHeaderStyle: CSSProperties = {
|
|
321
|
+
display: "flex",
|
|
322
|
+
alignItems: "center",
|
|
323
|
+
justifyContent: "space-between",
|
|
324
|
+
gap: 12,
|
|
325
|
+
padding: 16,
|
|
326
|
+
borderBottom: `1px solid ${GRAPH_THEME.ui.surface.panelBorder}`,
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const listTitleStyle: CSSProperties = {
|
|
330
|
+
color: GRAPH_THEME.ui.text.strong,
|
|
331
|
+
fontSize: 14,
|
|
332
|
+
fontWeight: 700,
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const listCountStyle: CSSProperties = {
|
|
336
|
+
color: GRAPH_THEME.ui.text.muted,
|
|
337
|
+
fontSize: 11,
|
|
338
|
+
marginTop: 3,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const iconButtonStyle: CSSProperties = {
|
|
342
|
+
display: "inline-grid",
|
|
343
|
+
placeItems: "center",
|
|
344
|
+
width: 30,
|
|
345
|
+
height: 30,
|
|
346
|
+
borderRadius: 8,
|
|
347
|
+
border: `1px solid ${GRAPH_THEME.ui.surface.panelBorder}`,
|
|
348
|
+
background: "rgba(255, 255, 255, 0.04)",
|
|
349
|
+
color: GRAPH_THEME.ui.text.body,
|
|
350
|
+
cursor: "pointer",
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const memoryListStyle: CSSProperties = {
|
|
354
|
+
display: "flex",
|
|
355
|
+
flexDirection: "column",
|
|
356
|
+
gap: 6,
|
|
357
|
+
minHeight: 0,
|
|
358
|
+
padding: 10,
|
|
359
|
+
overflowY: "auto",
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const memoryButtonStyle: CSSProperties = {
|
|
363
|
+
display: "flex",
|
|
364
|
+
flexDirection: "column",
|
|
365
|
+
alignItems: "flex-start",
|
|
366
|
+
gap: 5,
|
|
367
|
+
padding: 10,
|
|
368
|
+
borderRadius: 9,
|
|
369
|
+
border: "1px solid transparent",
|
|
370
|
+
background: "transparent",
|
|
371
|
+
color: GRAPH_THEME.ui.text.body,
|
|
372
|
+
textAlign: "left",
|
|
373
|
+
cursor: "pointer",
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const selectedMemoryButtonStyle: CSSProperties = {
|
|
377
|
+
border: `1px solid ${GRAPH_THEME.ui.control.activeBorder}`,
|
|
378
|
+
background: GRAPH_THEME.ui.timeline.playheadSoft,
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
const memoryTypeStyle: CSSProperties = {
|
|
382
|
+
color: GRAPH_THEME.ui.timeline.playhead,
|
|
383
|
+
fontSize: 10,
|
|
384
|
+
fontWeight: 700,
|
|
385
|
+
textTransform: "uppercase",
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const memoryIdStyle: CSSProperties = {
|
|
389
|
+
maxWidth: "100%",
|
|
390
|
+
overflow: "hidden",
|
|
391
|
+
color: GRAPH_THEME.ui.text.strong,
|
|
392
|
+
fontFamily: "monospace",
|
|
393
|
+
fontSize: 12,
|
|
394
|
+
textOverflow: "ellipsis",
|
|
395
|
+
whiteSpace: "nowrap",
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const memoryExcerptStyle: CSSProperties = {
|
|
399
|
+
display: "-webkit-box",
|
|
400
|
+
overflow: "hidden",
|
|
401
|
+
color: GRAPH_THEME.ui.text.muted,
|
|
402
|
+
fontSize: 11,
|
|
403
|
+
lineHeight: 1.45,
|
|
404
|
+
WebkitBoxOrient: "vertical",
|
|
405
|
+
WebkitLineClamp: 2,
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
const editorPanelStyle: CSSProperties = {
|
|
409
|
+
minWidth: 0,
|
|
410
|
+
minHeight: 0,
|
|
411
|
+
padding: 20,
|
|
412
|
+
overflowY: "auto",
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const selectionHeaderStyle: CSSProperties = {
|
|
416
|
+
display: "flex",
|
|
417
|
+
flexDirection: "column",
|
|
418
|
+
gap: 4,
|
|
419
|
+
marginBottom: 12,
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
const selectionLabelStyle: CSSProperties = {
|
|
423
|
+
color: GRAPH_THEME.ui.text.muted,
|
|
424
|
+
fontSize: 11,
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
const selectionIdStyle: CSSProperties = {
|
|
428
|
+
color: GRAPH_THEME.ui.text.strong,
|
|
429
|
+
fontFamily: "monospace",
|
|
430
|
+
fontSize: 14,
|
|
431
|
+
wordBreak: "break-all",
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const emptyStyle: CSSProperties = {
|
|
435
|
+
display: "flex",
|
|
436
|
+
flexDirection: "column",
|
|
437
|
+
alignItems: "center",
|
|
438
|
+
justifyContent: "center",
|
|
439
|
+
gap: 10,
|
|
440
|
+
minHeight: 160,
|
|
441
|
+
padding: 20,
|
|
442
|
+
color: GRAPH_THEME.ui.text.muted,
|
|
443
|
+
fontSize: 12,
|
|
444
|
+
textAlign: "center",
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
const retryButtonStyle: CSSProperties = {
|
|
448
|
+
padding: "6px 10px",
|
|
449
|
+
borderRadius: 7,
|
|
450
|
+
border: `1px solid ${GRAPH_THEME.ui.control.activeBorder}`,
|
|
451
|
+
background: GRAPH_THEME.ui.timeline.playheadSoft,
|
|
452
|
+
color: GRAPH_THEME.ui.timeline.playhead,
|
|
453
|
+
cursor: "pointer",
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const alertStyle: CSSProperties = {
|
|
457
|
+
marginBottom: 12,
|
|
458
|
+
padding: "10px 12px",
|
|
459
|
+
borderRadius: 8,
|
|
460
|
+
border: "1px solid rgba(248, 81, 73, 0.28)",
|
|
461
|
+
background: "rgba(248, 81, 73, 0.1)",
|
|
462
|
+
color: "#ffb4ad",
|
|
463
|
+
fontSize: 12,
|
|
464
|
+
};
|