@mazees/mark 5.0.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 +29 -0
- package/README.md +209 -0
- package/bin/mark.js +27 -0
- package/out/renderer/assets/icon-DHo2CYph.svg +1 -0
- package/out/renderer/assets/index-G2fADWO-.js +4768 -0
- package/out/renderer/assets/index-f3mVse3c.css +1 -0
- package/out/renderer/assets/music-cover-CG4vi3kZ.png +0 -0
- package/out/renderer/assets/poppins-devanagari-400-normal-CJDn6rn8.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-400-normal-CqVvlrh5.woff +0 -0
- package/out/renderer/assets/poppins-devanagari-500-normal-BIdkeU1p.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-500-normal-DMPDjHtT.woff +0 -0
- package/out/renderer/assets/poppins-devanagari-600-normal-ClASKHrr.woff +0 -0
- package/out/renderer/assets/poppins-devanagari-600-normal-STEjXBNN.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-700-normal-O-jipLrW.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-700-normal-fHs-vx92.woff +0 -0
- package/out/renderer/assets/poppins-latin-400-normal-BOb3E3N0.woff +0 -0
- package/out/renderer/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-500-normal-DGXqpDMm.woff +0 -0
- package/out/renderer/assets/poppins-latin-600-normal-BJdTmd5m.woff +0 -0
- package/out/renderer/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-700-normal-BVuQR_eA.woff +0 -0
- package/out/renderer/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-400-normal-DaBSavcJ.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-400-normal-by3JarPu.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-500-normal-CK-6C4Hw.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-500-normal-CgAe2rWW.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-600-normal-CAhIAdZj.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-600-normal-Df5ffKXP.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-700-normal-DctTR6Tg.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-700-normal-cby-RkWa.woff2 +0 -0
- package/out/renderer/favicon.ico +0 -0
- package/out/renderer/icon-256.png +0 -0
- package/out/renderer/icon.svg +1 -0
- package/out/renderer/index.html +25 -0
- package/out/renderer/manifest.json +25 -0
- package/out/renderer/robot-simulator.html +1640 -0
- package/package.json +106 -0
- package/src/cli/index.js +332 -0
- package/src/cli/monitor.js +413 -0
- package/src/cli/theme.js +347 -0
- package/src/launcher/MarkTray.cs +227 -0
- package/src/main/browser-agent.js +1132 -0
- package/src/main/git-service.js +90 -0
- package/src/main/google/google-calendar.js +69 -0
- package/src/main/google/google-drive.js +263 -0
- package/src/main/google/google-gmail.js +131 -0
- package/src/main/google/google-service.js +241 -0
- package/src/main/node-tools.js +23 -0
- package/src/main/pc-agent-scripts/mouse-locker.ps1 +76 -0
- package/src/main/pc-agent-scripts/ocr-region.ps1 +185 -0
- package/src/main/pc-agent-scripts/pc-daemon.ps1 +726 -0
- package/src/main/pc-agent-scripts/pc-overlay.ps1 +253 -0
- package/src/main/pc-agent-scripts/pick-folder.ps1 +33 -0
- package/src/main/pc-agent-scripts/read-ui.ps1 +181 -0
- package/src/main/pc-agent-scripts/take-screenshot.ps1 +24 -0
- package/src/main/pc-agent-scripts/win-action.ps1 +380 -0
- package/src/main/plugins/plugin-loader.js +306 -0
- package/src/main/skills/skill-manager.js +265 -0
- package/src/main/syntax-validator.js +455 -0
- package/src/main/task-daemon.js +117 -0
- package/src/main/telegram/telegram-service.js +835 -0
- package/src/main/tools/browser-tools.js +516 -0
- package/src/main/tools/file-tools.js +1126 -0
- package/src/main/tools/git-tools.js +79 -0
- package/src/main/tools/google-tools.js +566 -0
- package/src/main/tools/index.js +36 -0
- package/src/main/tools/media-tools.js +42 -0
- package/src/main/tools/system-tools.js +295 -0
- package/src/main/tools/task-tools.js +73 -0
- package/src/main/tools/telegram-tools.js +101 -0
- package/src/renderer/index.html +24 -0
- package/src/renderer/public/favicon.ico +0 -0
- package/src/renderer/public/icon-256.png +0 -0
- package/src/renderer/public/icon.svg +1 -0
- package/src/renderer/public/manifest.json +25 -0
- package/src/renderer/public/robot-simulator.html +1640 -0
- package/src/renderer/src/App.jsx +304 -0
- package/src/renderer/src/api/ai/awareness.js +294 -0
- package/src/renderer/src/api/ai/chatSummarizer.js +79 -0
- package/src/renderer/src/api/ai/contextCompactor.js +129 -0
- package/src/renderer/src/api/ai/contextManager.js +1130 -0
- package/src/renderer/src/api/ai/core.js +167 -0
- package/src/renderer/src/api/ai/index.js +4 -0
- package/src/renderer/src/api/ai/memoryGroomer.js +101 -0
- package/src/renderer/src/api/ai/persona.js +115 -0
- package/src/renderer/src/api/ai/planning.js +317 -0
- package/src/renderer/src/api/ai/relationship.js +177 -0
- package/src/renderer/src/api/ai/skillSynthesizer.js +168 -0
- package/src/renderer/src/api/ai/tools.js +167 -0
- package/src/renderer/src/api/ai/utils.js +359 -0
- package/src/renderer/src/api/db.js +1013 -0
- package/src/renderer/src/api/oramaStore.js +592 -0
- package/src/renderer/src/api/ragPipeline.js +87 -0
- package/src/renderer/src/api/subagent/subagentExecutor.js +780 -0
- package/src/renderer/src/api/subagent/subagentPrompt.js +44 -0
- package/src/renderer/src/api/subagent/subagentStore.js +173 -0
- package/src/renderer/src/api/taskExecutor.js +18 -0
- package/src/renderer/src/api/taskStore.js +315 -0
- package/src/renderer/src/api/tools/core-tools.js +707 -0
- package/src/renderer/src/api/tools/index.js +151 -0
- package/src/renderer/src/api/turnPairMigrator.js +200 -0
- package/src/renderer/src/api/vectorMemory.js +136 -0
- package/src/renderer/src/api/wakeWord.js +101 -0
- package/src/renderer/src/api/web-bridge.js +885 -0
- package/src/renderer/src/api/webSpeech.js +178 -0
- package/src/renderer/src/api/workspaceRag.js +76 -0
- package/src/renderer/src/assets/electron.svg +10 -0
- package/src/renderer/src/assets/icon.svg +1 -0
- package/src/renderer/src/assets/main.css +589 -0
- package/src/renderer/src/assets/music-cover.png +0 -0
- package/src/renderer/src/assets/wavy-lines.svg +25 -0
- package/src/renderer/src/components/Chat/ApprovalBubble.jsx +127 -0
- package/src/renderer/src/components/Chat/CodeBlock.jsx +83 -0
- package/src/renderer/src/components/Chat/DurableTaskBubble.jsx +455 -0
- package/src/renderer/src/components/Chat/FileDiffModal.jsx +328 -0
- package/src/renderer/src/components/Chat/GeminiWidgets.jsx +82 -0
- package/src/renderer/src/components/Chat/MemoryFooterBubble.jsx +34 -0
- package/src/renderer/src/components/Chat/MessageBubble.jsx +459 -0
- package/src/renderer/src/components/Chat/PluginExecutionBubble.jsx +41 -0
- package/src/renderer/src/components/Chat/ThinkingBubble.jsx +316 -0
- package/src/renderer/src/components/Chat/YoutubeSearchBubble.jsx +43 -0
- package/src/renderer/src/components/Chat/YoutubeSummaryBubble.jsx +40 -0
- package/src/renderer/src/components/Chat/index.js +11 -0
- package/src/renderer/src/components/ChatList.jsx +434 -0
- package/src/renderer/src/components/GlobalCameraManager.jsx +67 -0
- package/src/renderer/src/components/Versions.jsx +15 -0
- package/src/renderer/src/components/YoutubeMusicPlayer.jsx +375 -0
- package/src/renderer/src/components/camera/CameraPreview.jsx +236 -0
- package/src/renderer/src/components/config/AiEngineSection.jsx +363 -0
- package/src/renderer/src/components/config/CameraSection.jsx +100 -0
- package/src/renderer/src/components/config/PermissionsSection.jsx +130 -0
- package/src/renderer/src/components/config/ShortcutSection.jsx +102 -0
- package/src/renderer/src/components/config/VoiceSection.jsx +110 -0
- package/src/renderer/src/components/config/index.js +5 -0
- package/src/renderer/src/components/core/Avatar.jsx +2197 -0
- package/src/renderer/src/components/core/ConfirmModal.jsx +80 -0
- package/src/renderer/src/components/core/DraggableHoloCard.jsx +125 -0
- package/src/renderer/src/components/core/FloatingMenu.jsx +272 -0
- package/src/renderer/src/components/core/HoloCard.jsx +64 -0
- package/src/renderer/src/components/core/InputBar.jsx +1346 -0
- package/src/renderer/src/components/core/ProcessPanel.jsx +216 -0
- package/src/renderer/src/components/core/ResponseArea.jsx +149 -0
- package/src/renderer/src/components/core/StatusIndicator.jsx +59 -0
- package/src/renderer/src/components/core/ThoughtNeuralFlow.jsx +168 -0
- package/src/renderer/src/components/core/ToolClustersDeck.jsx +210 -0
- package/src/renderer/src/components/core/native-skills.js +43 -0
- package/src/renderer/src/components/neural-core/EmotionalCortexLobe.jsx +359 -0
- package/src/renderer/src/components/neural-core/NodeDissectionModal.jsx +57 -0
- package/src/renderer/src/components/neural-core/ProceduralMatrixLobe.jsx +193 -0
- package/src/renderer/src/components/neural-core/ProceduralSkillModal.jsx +53 -0
- package/src/renderer/src/components/neural-core/ResetAiModal.jsx +198 -0
- package/src/renderer/src/components/neural-core/SynapticMemoryLobe.jsx +204 -0
- package/src/renderer/src/components/neural-core/traitMeta.js +102 -0
- package/src/renderer/src/components/subagent/AgentChatFeed.jsx +603 -0
- package/src/renderer/src/components/subagent/AgentInspector.jsx +224 -0
- package/src/renderer/src/components/subagent/AgentSidebar.jsx +216 -0
- package/src/renderer/src/components/subagent/SubagentIntercom.jsx +572 -0
- package/src/renderer/src/components/subagent/SubagentTopologyMap.jsx +423 -0
- package/src/renderer/src/contexts/ApprovalContext.jsx +425 -0
- package/src/renderer/src/contexts/ChatContext.jsx +61 -0
- package/src/renderer/src/contexts/YoutubeMusicContext.jsx +333 -0
- package/src/renderer/src/data/faqData.js +202 -0
- package/src/renderer/src/hooks/agent/executeAgentTool.js +895 -0
- package/src/renderer/src/hooks/agent/index.js +4 -0
- package/src/renderer/src/hooks/agent/useMarkMusic.js +75 -0
- package/src/renderer/src/hooks/agent/useMarkPlan.js +2739 -0
- package/src/renderer/src/hooks/agent/useMarkState.js +173 -0
- package/src/renderer/src/hooks/agent/useMarkYoutube.js +82 -0
- package/src/renderer/src/hooks/agent/useRelationalGrowth.js +201 -0
- package/src/renderer/src/hooks/telegram/useTelegramBot.js +63 -0
- package/src/renderer/src/hooks/useAwareness.js +289 -0
- package/src/renderer/src/hooks/useChatArchiver.js +52 -0
- package/src/renderer/src/hooks/useConfirm.jsx +68 -0
- package/src/renderer/src/hooks/useMarkAgent.js +454 -0
- package/src/renderer/src/hooks/useMemoryGroomer.js +152 -0
- package/src/renderer/src/hooks/useVAD.js +511 -0
- package/src/renderer/src/hooks/useWebSpeechWakeWord.js +122 -0
- package/src/renderer/src/main.jsx +12 -0
- package/src/renderer/src/pages/ChatStudio.jsx +922 -0
- package/src/renderer/src/pages/Configuration.jsx +360 -0
- package/src/renderer/src/pages/GoogleWorkspace.jsx +293 -0
- package/src/renderer/src/pages/Guidebook.jsx +917 -0
- package/src/renderer/src/pages/Knowledge.jsx +241 -0
- package/src/renderer/src/pages/MarkHome.jsx +491 -0
- package/src/renderer/src/pages/NeuralCore.jsx +786 -0
- package/src/renderer/src/pages/Plugins.jsx +630 -0
- package/src/renderer/src/pages/SkillEditor.jsx +380 -0
- package/src/renderer/src/pages/Skills.jsx +219 -0
- package/src/renderer/src/pages/Subagents.jsx +342 -0
- package/src/renderer/src/pages/TelegramBot.jsx +343 -0
- package/src/renderer/src/utils/chatContentParser.js +203 -0
- package/src/renderer/src/utils/toolClusters.js +201 -0
- package/src/server/bin/sha3_wasm_bg.wasm +0 -0
- package/src/server/config-manager.js +57 -0
- package/src/server/index.js +195 -0
- package/src/server/launcher.js +87 -0
- package/src/server/memory/db-store.js +758 -0
- package/src/server/memory/orama-store.js +177 -0
- package/src/server/memory/vector-engine.js +109 -0
- package/src/server/routes/ai.routes.js +280 -0
- package/src/server/routes/awareness.routes.js +62 -0
- package/src/server/routes/chat.routes.js +61 -0
- package/src/server/routes/config.routes.js +41 -0
- package/src/server/routes/index.js +35 -0
- package/src/server/routes/integrations.routes.js +116 -0
- package/src/server/routes/memory.routes.js +256 -0
- package/src/server/routes/plugins.routes.js +72 -0
- package/src/server/routes/skills.routes.js +139 -0
- package/src/server/routes/subagents.routes.js +70 -0
- package/src/server/routes/tasks.routes.js +175 -0
- package/src/server/routes/workspace.routes.js +127 -0
- package/src/server/services/ai/ai-utils.js +161 -0
- package/src/server/services/ai/openai-provider.js +757 -0
- package/src/server/services/ai/web-provider.js +729 -0
- package/src/server/services/ai-bridge.js +46 -0
- package/src/server/services/deepseek-web.js +956 -0
- package/src/server/services/gemini-web.js +170 -0
- package/src/server/services/notification-service.js +91 -0
- package/src/server/services/updater.js +125 -0
- package/src/server/tools/awareness-tracker.js +292 -0
- package/src/server/tools/group-tools.js +1164 -0
- package/src/server/tools/media-tools.js +244 -0
- package/src/server/tools/pc-agent.js +327 -0
- package/src/server/tools/screen-service.js +51 -0
- package/src/server/ws-hub.js +168 -0
- package/src/shared/parsers/mark-tag-parser.js +275 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import React, { useEffect, useState, useMemo } from 'react'
|
|
2
|
+
import { Layers, Activity, Puzzle, ChevronRight, CheckCircle2 } from 'lucide-react'
|
|
3
|
+
import ProcessPanel from './ProcessPanel'
|
|
4
|
+
import { buildCompleteToolClusters } from '../../utils/toolClusters'
|
|
5
|
+
import { webApi } from '../../api/web-bridge'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ToolClustersDeck Component
|
|
9
|
+
* Docked Left Panel di MARK V5 yang merender seluruh kluster tools otonom,
|
|
10
|
+
* telemetry proses aktif, dan daftar custom plugins yang tersinkronisasi secara real-time.
|
|
11
|
+
*/
|
|
12
|
+
const ToolClustersDeck = ({ activeProcesses = [], dismissProcess, className = '' }) => {
|
|
13
|
+
const [selectedClusterKey, setSelectedClusterKey] = useState(null)
|
|
14
|
+
const [plugins, setPlugins] = useState([])
|
|
15
|
+
const [groupToolsSchema, setGroupToolsSchema] = useState(
|
|
16
|
+
() => webApi._groupToolsCache?.schema || {}
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
// Ambil data plugins & dengarkan event update
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
let isMounted = true
|
|
22
|
+
|
|
23
|
+
const loadPlugins = async () => {
|
|
24
|
+
try {
|
|
25
|
+
if (webApi && typeof webApi.getPlugins === 'function') {
|
|
26
|
+
const list = await webApi.getPlugins()
|
|
27
|
+
if (isMounted) setPlugins(list || [])
|
|
28
|
+
}
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error('[ToolClustersDeck] Gagal memuat plugins:', err)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const groupData = await webApi.getGroupTools()
|
|
35
|
+
if (isMounted && groupData?.schema) {
|
|
36
|
+
setGroupToolsSchema(groupData.schema)
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error('[ToolClustersDeck] Gagal memuat group tools:', err)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
loadPlugins()
|
|
44
|
+
|
|
45
|
+
let unsub = null
|
|
46
|
+
if (webApi && typeof webApi.onPluginsUpdated === 'function') {
|
|
47
|
+
unsub = webApi.onPluginsUpdated(() => {
|
|
48
|
+
loadPlugins()
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return () => {
|
|
53
|
+
isMounted = false
|
|
54
|
+
if (typeof unsub === 'function') unsub()
|
|
55
|
+
}
|
|
56
|
+
}, [])
|
|
57
|
+
|
|
58
|
+
// Bangun daftar kluster lengkap termasuk custom plugins
|
|
59
|
+
const clusters = useMemo(() => {
|
|
60
|
+
return buildCompleteToolClusters(plugins, groupToolsSchema)
|
|
61
|
+
}, [plugins, groupToolsSchema])
|
|
62
|
+
|
|
63
|
+
// Total count tools di seluruh kluster
|
|
64
|
+
const totalToolsCount = useMemo(() => {
|
|
65
|
+
return clusters.reduce((acc, c) => acc + (c.tools ? c.tools.length : 0), 0)
|
|
66
|
+
}, [clusters])
|
|
67
|
+
|
|
68
|
+
// Ekstrak nama tools yang sedang aktif berjalan secara real-time dari telemetry
|
|
69
|
+
const activeToolNames = useMemo(() => {
|
|
70
|
+
const active = new Set()
|
|
71
|
+
activeProcesses.forEach((p) => {
|
|
72
|
+
if (p.status === 'active' || p.status === 'running' || p.status === 'executing') {
|
|
73
|
+
if (p.type) active.add(p.type.toLowerCase())
|
|
74
|
+
if (p.name) active.add(p.name.toLowerCase())
|
|
75
|
+
if (p.tool) active.add(p.tool.toLowerCase())
|
|
76
|
+
if (p.data?.task) active.add(String(p.data.task).toLowerCase())
|
|
77
|
+
if (p.data?.tool) active.add(String(p.data.tool).toLowerCase())
|
|
78
|
+
if (p.data?.action) active.add(String(p.data.action).toLowerCase())
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
return active
|
|
82
|
+
}, [activeProcesses])
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<aside
|
|
86
|
+
className={`absolute left-6 top-18 bottom-24 w-72 lg:w-76 z-20 flex flex-col gap-2.5 pointer-events-auto ${className}`}
|
|
87
|
+
>
|
|
88
|
+
<div className="flex-1 bg-black/40 backdrop-blur-xl border border-white/5 rounded-2xl p-3 shadow-2xl flex flex-col min-h-0 overflow-hidden">
|
|
89
|
+
{/* Header */}
|
|
90
|
+
<div className="flex items-center justify-between pb-2 mb-2 border-b border-white/5 px-1">
|
|
91
|
+
<div className="flex items-center gap-2">
|
|
92
|
+
<Layers className="w-3.5 h-3.5 text-primary" />
|
|
93
|
+
<h3 className="text-xs font-bold font-mono tracking-wider text-white uppercase">
|
|
94
|
+
TOOL CLUSTERS
|
|
95
|
+
</h3>
|
|
96
|
+
</div>
|
|
97
|
+
<span className="text-[10px] font-mono text-white/40">
|
|
98
|
+
{clusters.length} Hubs · {totalToolsCount} Tools
|
|
99
|
+
</span>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
{/* Active Process In-Place Card (Jika ada proses/task yang sedang berjalan) */}
|
|
103
|
+
{activeProcesses && activeProcesses.length > 0 && (
|
|
104
|
+
<div className="mb-2 shrink-0 max-h-[35vh] overflow-y-auto no-scrollbar">
|
|
105
|
+
<ProcessPanel
|
|
106
|
+
processes={activeProcesses}
|
|
107
|
+
onDismiss={dismissProcess}
|
|
108
|
+
isEmbedded={true}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
)}
|
|
112
|
+
|
|
113
|
+
{/* List of Tool Clusters */}
|
|
114
|
+
<div className="flex-1 overflow-y-auto no-scrollbar space-y-1 pr-0.5">
|
|
115
|
+
{clusters.map((c) => {
|
|
116
|
+
const isClusterActive = c.tools.some((t) =>
|
|
117
|
+
t.matchTools.some(
|
|
118
|
+
(mt) =>
|
|
119
|
+
activeToolNames.has(mt) || [...activeToolNames].some((an) => an.includes(mt))
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
const isSelected = selectedClusterKey === c.key
|
|
123
|
+
const isCustomPluginCluster = c.key === 'custom_plugins'
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div key={c.id} className="flex flex-col">
|
|
127
|
+
<button
|
|
128
|
+
onClick={() => setSelectedClusterKey(isSelected ? null : c.key)}
|
|
129
|
+
className={`w-full flex items-center justify-between px-2.5 py-1.5 rounded-xl text-xs font-mono transition-all cursor-pointer ${
|
|
130
|
+
isClusterActive
|
|
131
|
+
? 'bg-primary/20 text-white font-semibold shadow-[0_0_10px_rgba(0,255,204,0.2)]'
|
|
132
|
+
: isSelected
|
|
133
|
+
? 'bg-white/10 text-white'
|
|
134
|
+
: 'text-white/70 hover:text-white hover:bg-white/5'
|
|
135
|
+
}`}
|
|
136
|
+
>
|
|
137
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
138
|
+
{isCustomPluginCluster ? (
|
|
139
|
+
<Puzzle className="w-2.5 h-2.5 text-purple-400 shrink-0" />
|
|
140
|
+
) : (
|
|
141
|
+
<span
|
|
142
|
+
className={`w-2 h-2 rounded-full shrink-0 ${isClusterActive ? 'animate-ping' : ''}`}
|
|
143
|
+
style={{ backgroundColor: c.color }}
|
|
144
|
+
/>
|
|
145
|
+
)}
|
|
146
|
+
<span className="truncate">{c.name}</span>
|
|
147
|
+
</div>
|
|
148
|
+
<div className="flex items-center gap-1.5 shrink-0">
|
|
149
|
+
{isClusterActive && (
|
|
150
|
+
<span className="px-1.5 py-0.2 rounded text-[8px] bg-primary text-black font-bold uppercase">
|
|
151
|
+
RUN
|
|
152
|
+
</span>
|
|
153
|
+
)}
|
|
154
|
+
<span className="text-[10px] opacity-40">({c.tools.length})</span>
|
|
155
|
+
</div>
|
|
156
|
+
</button>
|
|
157
|
+
|
|
158
|
+
{/* Expanded Sub-Tools */}
|
|
159
|
+
{isSelected && (
|
|
160
|
+
<div className="pl-4 pr-1 py-1 flex flex-col gap-1 border-l border-white/10 ml-2.5 my-1 animate-[holo-project-in_0.15s_ease-out_forwards]">
|
|
161
|
+
{c.tools.map((t) => {
|
|
162
|
+
const isToolActive = t.matchTools.some(
|
|
163
|
+
(mt) =>
|
|
164
|
+
activeToolNames.has(mt) ||
|
|
165
|
+
[...activeToolNames].some((an) => an.includes(mt))
|
|
166
|
+
)
|
|
167
|
+
return (
|
|
168
|
+
<div
|
|
169
|
+
key={t.id}
|
|
170
|
+
title={t.description || t.name}
|
|
171
|
+
className={`px-2 py-1 rounded-lg text-[10px] font-mono flex items-center justify-between transition-colors ${
|
|
172
|
+
isToolActive
|
|
173
|
+
? 'bg-primary text-black font-bold shadow-sm'
|
|
174
|
+
: 'text-white/60 hover:text-white hover:bg-white/5'
|
|
175
|
+
}`}
|
|
176
|
+
>
|
|
177
|
+
<div className="flex items-center gap-1.5 truncate flex-1 pr-1">
|
|
178
|
+
<span
|
|
179
|
+
className="w-1.5 h-1.5 rounded-full shrink-0"
|
|
180
|
+
style={{ backgroundColor: t.color || c.color }}
|
|
181
|
+
/>
|
|
182
|
+
<span className="truncate">{t.name}</span>
|
|
183
|
+
</div>
|
|
184
|
+
{isToolActive && (
|
|
185
|
+
<span className="w-1.5 h-1.5 rounded-full bg-black animate-pulse shrink-0" />
|
|
186
|
+
)}
|
|
187
|
+
</div>
|
|
188
|
+
)
|
|
189
|
+
})}
|
|
190
|
+
</div>
|
|
191
|
+
)}
|
|
192
|
+
</div>
|
|
193
|
+
)
|
|
194
|
+
})}
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
{/* Bottom Telemetry One-Liner */}
|
|
198
|
+
<div className="pt-2 mt-1 border-t border-white/5 flex items-center justify-between text-[11px] font-mono text-white/50 px-1">
|
|
199
|
+
<div className="flex items-center gap-1.5">
|
|
200
|
+
<Activity className="w-3 h-3 text-primary" />
|
|
201
|
+
<span>Active Process</span>
|
|
202
|
+
</div>
|
|
203
|
+
<span className="font-bold text-primary">{activeProcesses.length} Active</span>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</aside>
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export default React.memo(ToolClustersDeck)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const NATIVE_SKILLS = [
|
|
2
|
+
{
|
|
3
|
+
name: 'task',
|
|
4
|
+
description:
|
|
5
|
+
'Membuat dan mengeksekusi alur tugas multi-langkah terstruktur (Durable Tasks / Task Workflow)',
|
|
6
|
+
content: `
|
|
7
|
+
# SISTEM INSTRUKSI SKILL "/task" (DURABLE TASK WORKFLOW)
|
|
8
|
+
Kamu telah diinstruksikan oleh user untuk mengaktifkan fitur **/task** (Task Workflow)!
|
|
9
|
+
|
|
10
|
+
## ALUR KERJA WAJIB:
|
|
11
|
+
1. INISIASI ALUR KERJA: Panggil tool 'create_agent_task' sebagai tindakan PERTAMA. DILARANG memanggil tool lain (seperti run-powershell, node, dll) atau merespon dengan teks sebelum memanggil 'create_agent_task'.
|
|
12
|
+
2. EKSEKUSI TAHAP AKTIF (DI WORKSPACE PENGGUNA):
|
|
13
|
+
- Kerjakan sasaran dan target deliverable tahap aktif HANYA di direktori workspace proyek pengguna saat ini menggunakan tool koding yang relevan (seperti 'write-file', 'replace-content', 'read-file', 'run-powershell').
|
|
14
|
+
- DILARANG LANGSUNG MEMANGGIL 'mark_done_task' SEBELUM PEKERJAAN ATAU FILE DELIVERABLE TAHAP TERSEBUT SELESAI KAMU BUAT!
|
|
15
|
+
- DILARANG KERAS mencari, membaca, atau mengotak-atik kode internal aplikasi MARK ('src/', 'better-sqlite3', file tool agent, dll)!
|
|
16
|
+
- DILARANG menyelesaikan seluruh proyek di Tahap 1.
|
|
17
|
+
3. PENGUJIAN & VERIFIKASI WAJIB (TEST & VERIFICATION):
|
|
18
|
+
- Sebelum menandai suatu tahap selesai, kamu WAJIB memverifikasi atau menguji hasil deliverable tahap tersebut (misal: cek keberadaan & integritas file dengan 'read-file', uji eksekusi script dengan 'run-powershell', atau validasi sintaks).
|
|
19
|
+
- DILARANG KERAS memanggil 'mark_done_task' tanpa melakukan verifikasi riil!
|
|
20
|
+
4. PENYELESAIAN TAHAP (ONE-SHOT COMPLETION):
|
|
21
|
+
- 'mark_done_task' BUKAN alat untuk menyimpan draf atau cicilan progress sedikit demi sedikit! Panggil 'mark_done_task' HANYA TEPAT 1 KALI di akhir tahap saat deliverable tahap tersebut 100% tuntas dan teruji.
|
|
22
|
+
- Panggil 'mark_done_task' dengan parameter:
|
|
23
|
+
* "taskId": ID task yang sedang berjalan
|
|
24
|
+
* "stepIndex": Nomor tahap yang diselesaikan (1-based, misal: 1)
|
|
25
|
+
* "verificationProof": Bukti konkret hasil pengujian/verifikasi bahwa deliverable berfungsi (wajib diisi minimal 15 karakter)
|
|
26
|
+
* "artifactContent": Isi lengkap dokumen markdown (.md) hasil pengerjaan/spesifikasi tahap ini
|
|
27
|
+
* "summary": Ringkasan hasil
|
|
28
|
+
- DILARANG KERAS memanggil 'mark_done_task' berulang kali untuk tahap yang sama.
|
|
29
|
+
5. TRANSISI KE TAHAP BERIKUTNYA:
|
|
30
|
+
- Setelah 'mark_done_task' berhasil dipanggil untuk Tahap N, DILARANG memanggil 'read_task' untuk membaca ulang artefak yang baru saja kamu simpan sendiri!
|
|
31
|
+
- Langsung kerjakan deliverable Tahap N+1 di direktori workspace pengguna.
|
|
32
|
+
6. TAHAP TERAKHIR & RANGKUMAN PENUTUP:
|
|
33
|
+
- Pada TAHAP TERAKHIR dari Task Workflow, saat memanggil 'mark_done_task', kamu WAJIB mengisi parameter 'summary' dengan ringkasan komprehensif seluruh alur kerja proyek dari awal hingga akhir.
|
|
34
|
+
- Begitu tahap terakhir berhasil di-mark_done_task, alur kerja selesai 100% dan sistem langsung memutus proses serta menampilkan rangkuman akhir tersebut kepada pengguna. DILARANG memanggil tool apapun lagi.`
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'plan',
|
|
38
|
+
description: 'Alias untuk /task: Menjalankan alur pengerjaan tugas terstruktur (Task Workflow)',
|
|
39
|
+
content: `
|
|
40
|
+
# ALIAS PERINTAH: /plan -> /task
|
|
41
|
+
Alihkan instruksi ini ke sistem Task Workflow. Segera panggil tool 'create_agent_task' sebagai tindakan pertama dengan judul, sasaran menyeluruh, dan 3-5 tahapan eksekusi terstruktur! Setiap tahap dikerjakan di workspace sebelum diselesaikan dengan 'mark_done_task'.`
|
|
42
|
+
}
|
|
43
|
+
]
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FaFire,
|
|
3
|
+
FaBrain,
|
|
4
|
+
FaClock,
|
|
5
|
+
FaCommentDots,
|
|
6
|
+
FaChevronRight,
|
|
7
|
+
FaShieldAlt,
|
|
8
|
+
FaChartBar,
|
|
9
|
+
FaTheaterMasks,
|
|
10
|
+
FaRobot,
|
|
11
|
+
FaDatabase,
|
|
12
|
+
FaDownload,
|
|
13
|
+
FaUpload,
|
|
14
|
+
FaTrash
|
|
15
|
+
} from 'react-icons/fa'
|
|
16
|
+
import { TRAIT_META, describeLevel, describePersonality } from './traitMeta'
|
|
17
|
+
|
|
18
|
+
export const EmotionalCortexLobe = ({
|
|
19
|
+
traits,
|
|
20
|
+
isFullView = false,
|
|
21
|
+
onNavigateToFull,
|
|
22
|
+
onResetAi,
|
|
23
|
+
onExportDatabase,
|
|
24
|
+
onRestoreDatabase,
|
|
25
|
+
isExportingDb = false,
|
|
26
|
+
isRestoringDb = false
|
|
27
|
+
}) => {
|
|
28
|
+
if (isFullView) {
|
|
29
|
+
return (
|
|
30
|
+
<div className="flex-1 flex flex-col gap-6 min-h-0 overflow-y-auto custom-scrollbar max-w-5xl mx-auto w-full pb-12">
|
|
31
|
+
{/* Personality Status Banner */}
|
|
32
|
+
<div className="p-6 rounded-2xl bg-base-200/70 border border-white/5 backdrop-blur-md shadow-lg">
|
|
33
|
+
<div className="flex items-center justify-between mb-3">
|
|
34
|
+
<span className="text-xs font-mono font-bold text-primary flex items-center gap-2 uppercase tracking-wider">
|
|
35
|
+
<FaBrain className="text-primary" /> Status Kepribadian & Karakter Mark
|
|
36
|
+
</span>
|
|
37
|
+
{traits?.evalCount > 0 && (
|
|
38
|
+
<span className="text-xs font-mono text-base-content/50 flex items-center gap-2">
|
|
39
|
+
<FaClock /> Evaluasi ke-{traits.evalCount}
|
|
40
|
+
</span>
|
|
41
|
+
)}
|
|
42
|
+
</div>
|
|
43
|
+
<p className="text-base text-base-content/90 leading-relaxed font-sans font-medium">
|
|
44
|
+
{describePersonality(traits)}
|
|
45
|
+
</p>
|
|
46
|
+
{traits?.lastEvaluation && (
|
|
47
|
+
<p className="text-xs text-base-content/40 mt-3 font-mono">
|
|
48
|
+
Terakhir diperbarui:{' '}
|
|
49
|
+
{new Date(traits.lastEvaluation).toLocaleString('id-ID', {
|
|
50
|
+
dateStyle: 'medium',
|
|
51
|
+
timeStyle: 'short'
|
|
52
|
+
})}
|
|
53
|
+
</p>
|
|
54
|
+
)}
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
{/* 5 Trait Rings Grid */}
|
|
58
|
+
<div>
|
|
59
|
+
<h3 className="text-xs font-bold font-mono text-base-content/60 uppercase tracking-wider mb-3">
|
|
60
|
+
5 Dimensi Sifat & Karakter
|
|
61
|
+
</h3>
|
|
62
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3">
|
|
63
|
+
{TRAIT_META.map((t) => {
|
|
64
|
+
const val = traits?.[t.key] ?? 0.5
|
|
65
|
+
const pct = Math.round(val * 100)
|
|
66
|
+
const r = 38
|
|
67
|
+
const circ = 2 * Math.PI * r
|
|
68
|
+
const offset = circ - (pct / 100) * circ
|
|
69
|
+
return (
|
|
70
|
+
<div
|
|
71
|
+
key={t.key}
|
|
72
|
+
className={`p-4 rounded-2xl bg-base-200/50 border border-white/5 ring-1 ${t.ring} flex flex-col items-center text-center gap-3 transition-all hover:bg-base-200/80 shadow-md`}
|
|
73
|
+
>
|
|
74
|
+
<div className="relative w-24 h-24">
|
|
75
|
+
<svg className="w-full h-full -rotate-90" viewBox="0 0 100 100">
|
|
76
|
+
<circle
|
|
77
|
+
cx="50"
|
|
78
|
+
cy="50"
|
|
79
|
+
r={r}
|
|
80
|
+
fill="none"
|
|
81
|
+
strokeWidth="5"
|
|
82
|
+
className="stroke-white/5"
|
|
83
|
+
/>
|
|
84
|
+
<circle
|
|
85
|
+
cx="50"
|
|
86
|
+
cy="50"
|
|
87
|
+
r={r}
|
|
88
|
+
fill="none"
|
|
89
|
+
strokeWidth="5"
|
|
90
|
+
strokeLinecap="round"
|
|
91
|
+
strokeDasharray={circ}
|
|
92
|
+
strokeDashoffset={offset}
|
|
93
|
+
stroke={t.hex}
|
|
94
|
+
className="transition-all duration-1000 ease-out"
|
|
95
|
+
/>
|
|
96
|
+
</svg>
|
|
97
|
+
<div
|
|
98
|
+
className={`absolute inset-0 flex flex-col items-center justify-center ${t.color}`}
|
|
99
|
+
>
|
|
100
|
+
<t.icon className="text-xl mb-0.5 opacity-90" />
|
|
101
|
+
<span className="text-xs font-bold font-mono text-base-content">{pct}%</span>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<div>
|
|
105
|
+
<p className={`text-xs font-bold font-mono ${t.color}`}>{t.label}</p>
|
|
106
|
+
<p className="text-[10px] text-base-content/50 leading-tight mt-0.5">
|
|
107
|
+
{t.desc}
|
|
108
|
+
</p>
|
|
109
|
+
<span className="inline-block mt-2 px-2.5 py-0.5 rounded-full text-[10px] font-mono font-medium bg-base-300 border border-white/5 text-base-content/70">
|
|
110
|
+
{describeLevel(val)}
|
|
111
|
+
</span>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
)
|
|
115
|
+
})}
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
{/* Reasoning Log */}
|
|
120
|
+
{traits?.reasoning && (
|
|
121
|
+
<div className="p-5 rounded-2xl bg-base-200/60 border border-white/5 backdrop-blur-md">
|
|
122
|
+
<p className="text-xs font-mono font-bold text-base-content/60 mb-2 flex items-center gap-2">
|
|
123
|
+
<FaCommentDots className="text-primary" /> ALASAN PERUBAHAN SIKAP TERAKHIR:
|
|
124
|
+
</p>
|
|
125
|
+
<p className="text-sm text-base-content/80 italic font-sans leading-relaxed bg-base-300/60 p-4 rounded-xl border border-white/5">
|
|
126
|
+
“{traits.reasoning}”
|
|
127
|
+
</p>
|
|
128
|
+
</div>
|
|
129
|
+
)}
|
|
130
|
+
|
|
131
|
+
{/* Stats Grid */}
|
|
132
|
+
<div>
|
|
133
|
+
<h3 className="text-xs font-bold font-mono text-base-content/60 uppercase tracking-wider mb-3">
|
|
134
|
+
Ringkasan Statistik Sifat
|
|
135
|
+
</h3>
|
|
136
|
+
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3">
|
|
137
|
+
{[
|
|
138
|
+
{
|
|
139
|
+
label: 'Total Evaluasi',
|
|
140
|
+
value: traits?.evalCount || 0,
|
|
141
|
+
icon: FaChartBar,
|
|
142
|
+
color: 'text-primary',
|
|
143
|
+
sub: 'Frekuensi adaptasi'
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
label: 'Kehangatan',
|
|
147
|
+
value: ((traits?.warmth || 0.5) * 100).toFixed(0) + '%',
|
|
148
|
+
icon: FaFire,
|
|
149
|
+
color: 'text-error',
|
|
150
|
+
sub: describeLevel(traits?.warmth || 0.5)
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
label: 'Kepercayaan',
|
|
154
|
+
value: ((traits?.trust || 0.5) * 100).toFixed(0) + '%',
|
|
155
|
+
icon: FaShieldAlt,
|
|
156
|
+
color: 'text-success',
|
|
157
|
+
sub: describeLevel(traits?.trust || 0.5)
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
label: 'Sarkasme',
|
|
161
|
+
value: ((traits?.sarcasm_level || 0.5) * 100).toFixed(0) + '%',
|
|
162
|
+
icon: FaTheaterMasks,
|
|
163
|
+
color: 'text-warning',
|
|
164
|
+
sub: describeLevel(traits?.sarcasm_level || 0.5)
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
label: 'Kepatuhan',
|
|
168
|
+
value: ((traits?.obedience || 0.5) * 100).toFixed(0) + '%',
|
|
169
|
+
icon: FaRobot,
|
|
170
|
+
color: 'text-secondary',
|
|
171
|
+
sub: describeLevel(traits?.obedience || 0.5)
|
|
172
|
+
}
|
|
173
|
+
].map((stat, i) => {
|
|
174
|
+
const StatIcon = stat.icon
|
|
175
|
+
return (
|
|
176
|
+
<div
|
|
177
|
+
key={i}
|
|
178
|
+
className="p-3.5 rounded-xl bg-base-200/50 border border-white/5 hover:bg-base-200/80 transition-colors"
|
|
179
|
+
>
|
|
180
|
+
<div className="flex items-center gap-1.5 mb-1.5">
|
|
181
|
+
<StatIcon className={`text-sm ${stat.color}`} />
|
|
182
|
+
<span className="text-[11px] text-base-content/50 leading-none">
|
|
183
|
+
{stat.label}
|
|
184
|
+
</span>
|
|
185
|
+
</div>
|
|
186
|
+
<p className={`text-lg font-bold font-mono leading-none ${stat.color}`}>
|
|
187
|
+
{stat.value}
|
|
188
|
+
</p>
|
|
189
|
+
<p className="text-[10px] text-base-content/40 mt-1.5 leading-none">{stat.sub}</p>
|
|
190
|
+
</div>
|
|
191
|
+
)
|
|
192
|
+
})}
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
{/* Pencadangan, Migrasi & Pemulihan Database */}
|
|
197
|
+
<div className="p-5 rounded-2xl bg-base-200/70 border border-white/5 backdrop-blur-md shadow-lg flex flex-col md:flex-row items-start md:items-center justify-between gap-4">
|
|
198
|
+
<div>
|
|
199
|
+
<h4 className="text-xs font-bold font-mono text-base-content/80 uppercase tracking-wider flex items-center gap-2">
|
|
200
|
+
<FaDatabase className="text-primary" /> Pencadangan & Migrasi Database
|
|
201
|
+
</h4>
|
|
202
|
+
<p className="text-xs text-base-content/60 mt-1 max-w-xl">
|
|
203
|
+
Simpan atau pulihkan seluruh memori kognitif, Skill Yang Di Pelajari, arsip
|
|
204
|
+
percakapan, dan dokumen Mark dalam format JSON untuk cadangan atau migrasi antar
|
|
205
|
+
perangkat.
|
|
206
|
+
</p>
|
|
207
|
+
</div>
|
|
208
|
+
<div className="flex flex-wrap items-center gap-2 shrink-0">
|
|
209
|
+
{onExportDatabase && (
|
|
210
|
+
<button
|
|
211
|
+
type="button"
|
|
212
|
+
onClick={onExportDatabase}
|
|
213
|
+
disabled={isExportingDb || isRestoringDb}
|
|
214
|
+
className="btn btn-sm btn-outline btn-primary rounded-xl font-mono text-xs shadow-sm flex items-center gap-2"
|
|
215
|
+
>
|
|
216
|
+
{isExportingDb ? (
|
|
217
|
+
<span className="loading loading-spinner loading-xs" />
|
|
218
|
+
) : (
|
|
219
|
+
<FaDownload size={11} />
|
|
220
|
+
)}
|
|
221
|
+
Backup Database (JSON)
|
|
222
|
+
</button>
|
|
223
|
+
)}
|
|
224
|
+
{onRestoreDatabase && (
|
|
225
|
+
<button
|
|
226
|
+
type="button"
|
|
227
|
+
onClick={onRestoreDatabase}
|
|
228
|
+
disabled={isExportingDb || isRestoringDb}
|
|
229
|
+
className="btn btn-sm btn-outline btn-warning rounded-xl font-mono text-xs shadow-sm flex items-center gap-2"
|
|
230
|
+
>
|
|
231
|
+
{isRestoringDb ? (
|
|
232
|
+
<span className="loading loading-spinner loading-xs" />
|
|
233
|
+
) : (
|
|
234
|
+
<FaUpload size={11} />
|
|
235
|
+
)}
|
|
236
|
+
Restore Database
|
|
237
|
+
</button>
|
|
238
|
+
)}
|
|
239
|
+
<button
|
|
240
|
+
type="button"
|
|
241
|
+
onClick={onResetAi}
|
|
242
|
+
disabled={isExportingDb || isRestoringDb}
|
|
243
|
+
className="btn btn-sm btn-outline btn-error rounded-xl font-mono text-xs shadow-sm flex items-center gap-1.5"
|
|
244
|
+
>
|
|
245
|
+
<FaTrash size={11} />
|
|
246
|
+
Reset Total AI
|
|
247
|
+
</button>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Embedded Column
|
|
255
|
+
return (
|
|
256
|
+
<div className="lg:col-span-4 bg-base-200/50 backdrop-blur-md border border-white/5 rounded-2xl p-4 flex flex-col min-h-0 overflow-y-auto custom-scrollbar shadow-xl">
|
|
257
|
+
<div className="flex items-center justify-between border-b border-white/5 pb-3 mb-3">
|
|
258
|
+
<div className="flex items-center gap-2 text-sm font-bold font-mono text-base-content">
|
|
259
|
+
<FaFire className="text-error" /> SIFAT & KARAKTER
|
|
260
|
+
</div>
|
|
261
|
+
{onNavigateToFull && (
|
|
262
|
+
<button
|
|
263
|
+
type="button"
|
|
264
|
+
onClick={onNavigateToFull}
|
|
265
|
+
className="text-[10px] font-mono text-base-content/50 hover:text-base-content flex items-center gap-1 cursor-pointer transition-colors"
|
|
266
|
+
>
|
|
267
|
+
Lihat Penuh <FaChevronRight size={8} />
|
|
268
|
+
</button>
|
|
269
|
+
)}
|
|
270
|
+
</div>
|
|
271
|
+
|
|
272
|
+
{/* Ringkasan Kepribadian */}
|
|
273
|
+
<div className="p-3 bg-base-300/60 rounded-xl border border-white/5 mb-3 text-xs text-base-content/80 leading-relaxed font-sans">
|
|
274
|
+
<span className="font-bold text-primary block mb-1 font-mono text-[10px] uppercase">
|
|
275
|
+
SIKAP MARK SAAT INI:
|
|
276
|
+
</span>
|
|
277
|
+
{describePersonality(traits)}
|
|
278
|
+
</div>
|
|
279
|
+
|
|
280
|
+
{/* 5 Trait Progress Bars */}
|
|
281
|
+
<div className="space-y-2.5 flex-1">
|
|
282
|
+
{TRAIT_META.map((t) => {
|
|
283
|
+
const val = traits?.[t.key] ?? 0.5
|
|
284
|
+
const pct = Math.round(val * 100)
|
|
285
|
+
return (
|
|
286
|
+
<div
|
|
287
|
+
key={t.key}
|
|
288
|
+
className="p-2.5 bg-base-300/40 rounded-xl border border-white/5 flex flex-col gap-1.5"
|
|
289
|
+
>
|
|
290
|
+
<div className="flex items-center justify-between text-xs font-mono">
|
|
291
|
+
<span className={`flex items-center gap-1.5 font-medium ${t.color}`}>
|
|
292
|
+
<t.icon className="text-xs" /> {t.label}
|
|
293
|
+
</span>
|
|
294
|
+
<span className="font-semibold text-base-content/70">
|
|
295
|
+
{pct}% ({describeLevel(val)})
|
|
296
|
+
</span>
|
|
297
|
+
</div>
|
|
298
|
+
<div className="w-full h-1.5 bg-base-content/10 rounded-full overflow-hidden">
|
|
299
|
+
<div
|
|
300
|
+
className="h-full rounded-full transition-all duration-700"
|
|
301
|
+
style={{ width: `${pct}%`, backgroundColor: t.hex }}
|
|
302
|
+
/>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
)
|
|
306
|
+
})}
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
{/* Database Backup, Restore & Reset Buttons */}
|
|
310
|
+
<div className="mt-3 pt-3 border-t border-white/5 space-y-2">
|
|
311
|
+
<div className="grid grid-cols-2 gap-2">
|
|
312
|
+
{onExportDatabase && (
|
|
313
|
+
<button
|
|
314
|
+
type="button"
|
|
315
|
+
onClick={onExportDatabase}
|
|
316
|
+
disabled={isExportingDb || isRestoringDb}
|
|
317
|
+
className="btn btn-xs btn-outline btn-primary rounded-lg font-mono text-[10px] flex items-center justify-center gap-1.5"
|
|
318
|
+
title="Backup Database ke JSON"
|
|
319
|
+
>
|
|
320
|
+
{isExportingDb ? (
|
|
321
|
+
<span className="loading loading-spinner loading-xs" />
|
|
322
|
+
) : (
|
|
323
|
+
<FaDownload size={9} />
|
|
324
|
+
)}
|
|
325
|
+
Backup JSON
|
|
326
|
+
</button>
|
|
327
|
+
)}
|
|
328
|
+
{onRestoreDatabase && (
|
|
329
|
+
<button
|
|
330
|
+
type="button"
|
|
331
|
+
onClick={onRestoreDatabase}
|
|
332
|
+
disabled={isExportingDb || isRestoringDb}
|
|
333
|
+
className="btn btn-xs btn-outline btn-warning rounded-lg font-mono text-[10px] flex items-center justify-center gap-1.5"
|
|
334
|
+
title="Pulihkan Database dari JSON"
|
|
335
|
+
>
|
|
336
|
+
{isRestoringDb ? (
|
|
337
|
+
<span className="loading loading-spinner loading-xs" />
|
|
338
|
+
) : (
|
|
339
|
+
<FaUpload size={9} />
|
|
340
|
+
)}
|
|
341
|
+
Restore JSON
|
|
342
|
+
</button>
|
|
343
|
+
)}
|
|
344
|
+
</div>
|
|
345
|
+
|
|
346
|
+
<button
|
|
347
|
+
type="button"
|
|
348
|
+
onClick={onResetAi}
|
|
349
|
+
disabled={isExportingDb || isRestoringDb}
|
|
350
|
+
className="w-full py-1.5 bg-error/10 hover:bg-error/20 text-error border border-error/20 rounded-xl text-xs font-mono font-medium transition-all cursor-pointer flex items-center justify-center gap-1.5"
|
|
351
|
+
>
|
|
352
|
+
<FaTrash size={10} /> Reset Total AI
|
|
353
|
+
</button>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export default EmotionalCortexLobe
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { FaTimes, FaTrash } from 'react-icons/fa'
|
|
3
|
+
|
|
4
|
+
export const NodeDissectionModal = ({ node, onClose, onDeleteNode }) => {
|
|
5
|
+
if (!node) return null
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<div className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-center justify-center p-4 animate-fade-in">
|
|
9
|
+
<div className="w-full max-w-lg bg-base-200 border border-white/10 rounded-2xl p-6 shadow-2xl">
|
|
10
|
+
<div className="flex items-center justify-between mb-3">
|
|
11
|
+
<span
|
|
12
|
+
className={`px-2.5 py-0.5 rounded-full text-xs font-mono font-bold ${
|
|
13
|
+
node.typeLabel === 'Explicit Memory'
|
|
14
|
+
? 'bg-secondary/20 text-secondary border border-secondary/30'
|
|
15
|
+
: node.typeLabel === 'Document Chunk'
|
|
16
|
+
? 'bg-warning/20 text-warning border border-warning/30'
|
|
17
|
+
: node.typeLabel === 'Learned Skill'
|
|
18
|
+
? 'bg-purple-500/20 text-purple-400 border border-purple-500/30'
|
|
19
|
+
: 'bg-primary/20 text-primary border border-primary/30'
|
|
20
|
+
}`}
|
|
21
|
+
>
|
|
22
|
+
{node.typeLabel || 'Data Memori'}
|
|
23
|
+
</span>
|
|
24
|
+
<button
|
|
25
|
+
type="button"
|
|
26
|
+
onClick={onClose}
|
|
27
|
+
className="text-base-content/40 hover:text-base-content cursor-pointer transition-colors"
|
|
28
|
+
>
|
|
29
|
+
<FaTimes size={14} />
|
|
30
|
+
</button>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<p className="text-xs font-mono text-base-content/50 mb-2">{node.date}</p>
|
|
34
|
+
<div className="p-3.5 bg-base-300/60 border border-white/5 rounded-xl text-sm font-sans text-base-content/90 max-h-60 overflow-y-auto custom-scrollbar mb-4 leading-relaxed whitespace-pre-wrap">
|
|
35
|
+
{node.fullText}
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div className="flex items-center justify-between pt-2">
|
|
39
|
+
<span className="text-[11px] font-mono text-base-content/40">ID: {node.id}</span>
|
|
40
|
+
{(node.typeLabel === 'Explicit Memory' ||
|
|
41
|
+
node.typeLabel === 'Chat Archive' ||
|
|
42
|
+
node.typeLabel === 'Learned Skill') && (
|
|
43
|
+
<button
|
|
44
|
+
type="button"
|
|
45
|
+
onClick={() => onDeleteNode(node)}
|
|
46
|
+
className="btn btn-xs btn-error btn-outline font-mono flex items-center gap-1.5"
|
|
47
|
+
>
|
|
48
|
+
<FaTrash size={11} /> Hapus Data Memori
|
|
49
|
+
</button>
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default NodeDissectionModal
|