@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,423 @@
|
|
|
1
|
+
import React, { useState, useMemo } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
Brain,
|
|
4
|
+
Bot,
|
|
5
|
+
Activity,
|
|
6
|
+
Send,
|
|
7
|
+
Terminal,
|
|
8
|
+
ExternalLink,
|
|
9
|
+
Layers,
|
|
10
|
+
Sparkles,
|
|
11
|
+
CheckCircle2,
|
|
12
|
+
AlertTriangle
|
|
13
|
+
} from 'lucide-react'
|
|
14
|
+
|
|
15
|
+
// Primary MARK Theme (Forest Theme)
|
|
16
|
+
const PRIMARY = '#1fb854'
|
|
17
|
+
const PRIMARY_DARK = '#142e22'
|
|
18
|
+
const WHITE = '#ffffff'
|
|
19
|
+
|
|
20
|
+
export default function SubagentTopologyMap({
|
|
21
|
+
subagents = [],
|
|
22
|
+
selectedId = null,
|
|
23
|
+
onSelectAgent = () => {},
|
|
24
|
+
onOpenIntercom = () => {},
|
|
25
|
+
onSendMessage = () => {}
|
|
26
|
+
}) {
|
|
27
|
+
const [hoveredId, setHoveredId] = useState(null)
|
|
28
|
+
const [quickInput, setQuickInput] = useState('')
|
|
29
|
+
const [isSending, setIsSending] = useState(false)
|
|
30
|
+
|
|
31
|
+
// Filter agent untuk topologi:
|
|
32
|
+
// Saat ada sub-agent yang sedang berjalan (running), HANYA tampilkan yang aktif agar diagram fokus & tidak penuh.
|
|
33
|
+
// Saat semua tugas selesai / idle, tampilkan seluruh sub-agent yang standby.
|
|
34
|
+
const displayAgents = useMemo(() => {
|
|
35
|
+
const running = subagents.filter((a) => a.status === 'running')
|
|
36
|
+
if (running.length > 0) {
|
|
37
|
+
return running
|
|
38
|
+
}
|
|
39
|
+
return subagents
|
|
40
|
+
}, [subagents])
|
|
41
|
+
|
|
42
|
+
// Layout geometry for constellation placement
|
|
43
|
+
const totalAgents = displayAgents.length
|
|
44
|
+
const center = { x: 340, y: 240 }
|
|
45
|
+
const radius = Math.min(180, Math.max(130, totalAgents * 24))
|
|
46
|
+
|
|
47
|
+
const nodes = useMemo(() => {
|
|
48
|
+
if (totalAgents === 0) return []
|
|
49
|
+
return displayAgents.map((agent, index) => {
|
|
50
|
+
const angle = (index / totalAgents) * 2 * Math.PI - Math.PI / 2
|
|
51
|
+
const x = center.x + radius * Math.cos(angle)
|
|
52
|
+
const y = center.y + radius * Math.sin(angle)
|
|
53
|
+
return {
|
|
54
|
+
...agent,
|
|
55
|
+
x,
|
|
56
|
+
y,
|
|
57
|
+
angle
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}, [displayAgents, totalAgents, center.x, center.y, radius])
|
|
61
|
+
|
|
62
|
+
const selectedAgent = useMemo(
|
|
63
|
+
() => subagents.find((a) => a.id === selectedId) || null,
|
|
64
|
+
[subagents, selectedId]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const activeCount = subagents.filter((a) => a.status === 'running').length
|
|
68
|
+
const idleCount = subagents.filter((a) => a.status === 'idle').length
|
|
69
|
+
const completedCount = subagents.filter((a) => a.status === 'completed').length
|
|
70
|
+
const failedCount = subagents.filter((a) => a.status === 'failed' || a.status === 'killed').length
|
|
71
|
+
|
|
72
|
+
const handleQuickSend = async (e) => {
|
|
73
|
+
e?.preventDefault()
|
|
74
|
+
if (!quickInput.trim() || !selectedAgent || isSending) return
|
|
75
|
+
setIsSending(true)
|
|
76
|
+
try {
|
|
77
|
+
await onSendMessage(selectedAgent.id, quickInput.trim())
|
|
78
|
+
setQuickInput('')
|
|
79
|
+
} finally {
|
|
80
|
+
setIsSending(false)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div className="flex-1 flex flex-col md:flex-row h-full overflow-hidden gap-4 font-['Poppins',sans-serif]">
|
|
86
|
+
{/* Visual Canvas Area */}
|
|
87
|
+
<div className="flex-1 bg-base-200/50 rounded-2xl border border-base-content/10 relative overflow-hidden flex flex-col items-center justify-center p-4 backdrop-blur-md">
|
|
88
|
+
{/* Subtle Ambient Radial Highlight */}
|
|
89
|
+
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,#1fb8540d_0%,transparent_70%)] pointer-events-none" />
|
|
90
|
+
|
|
91
|
+
{/* Top Minimal Telemetry Bar */}
|
|
92
|
+
<div className="absolute top-3 left-4 right-4 flex items-center justify-between pointer-events-none z-10">
|
|
93
|
+
<div className="flex items-center gap-2 bg-base-300/80 backdrop-blur-md px-3 py-1.5 rounded-xl border border-base-content/5 text-xs shadow-sm">
|
|
94
|
+
<span className="w-2 h-2 rounded-full bg-primary animate-pulse" />
|
|
95
|
+
<span className="font-semibold text-[11px] tracking-wide text-base-content/80">
|
|
96
|
+
Topology Network {activeCount > 0 ? '(Active Squad)' : '(Standby)'}
|
|
97
|
+
</span>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div className="flex items-center gap-2 font-mono text-[11px]">
|
|
101
|
+
{activeCount > 0 && (
|
|
102
|
+
<span className="px-2.5 py-1 bg-base-300/80 backdrop-blur-md rounded-lg border border-primary/30 flex items-center gap-1.5 text-primary shadow-sm font-semibold">
|
|
103
|
+
<span className="w-1.5 h-1.5 rounded-full bg-primary animate-ping" />
|
|
104
|
+
{activeCount} Aktif
|
|
105
|
+
</span>
|
|
106
|
+
)}
|
|
107
|
+
{idleCount > 0 && (
|
|
108
|
+
<span className="px-2.5 py-1 bg-base-300/80 backdrop-blur-md rounded-lg border border-base-content/5 flex items-center gap-1.5 text-base-content/80 shadow-sm">
|
|
109
|
+
<span className="w-1.5 h-1.5 rounded-full bg-primary/70" />
|
|
110
|
+
{idleCount} Standby
|
|
111
|
+
</span>
|
|
112
|
+
)}
|
|
113
|
+
{completedCount > 0 && (
|
|
114
|
+
<span className="px-2.5 py-1 bg-base-300/80 backdrop-blur-md rounded-lg border border-base-content/5 flex items-center gap-1.5 text-base-content/80 shadow-sm">
|
|
115
|
+
<span className="w-1.5 h-1.5 rounded-full bg-primary" />
|
|
116
|
+
{completedCount} Selesai
|
|
117
|
+
</span>
|
|
118
|
+
)}
|
|
119
|
+
{failedCount > 0 && (
|
|
120
|
+
<span className="px-2.5 py-1 bg-base-300/80 backdrop-blur-md rounded-lg border border-error/30 text-error flex items-center gap-1.5 shadow-sm">
|
|
121
|
+
{failedCount} Gagal
|
|
122
|
+
</span>
|
|
123
|
+
)}
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
{totalAgents === 0 ? (
|
|
128
|
+
<div className="flex flex-col items-center justify-center text-center p-8 z-10 text-base-content/40 space-y-2.5">
|
|
129
|
+
<div className="w-14 h-14 rounded-2xl bg-base-300/80 border border-base-content/10 flex items-center justify-center text-primary shadow-inner">
|
|
130
|
+
<Layers className="w-7 h-7 stroke-[1.5]" />
|
|
131
|
+
</div>
|
|
132
|
+
<div>
|
|
133
|
+
<p className="font-semibold text-sm text-base-content/70">
|
|
134
|
+
Belum Ada Sub-Agent
|
|
135
|
+
</p>
|
|
136
|
+
<p className="text-xs text-base-content/40 mt-0.5 max-w-sm">
|
|
137
|
+
Saat Mark mendelegasikan tugas ke sub-agent, topologi tim akan muncul di sini.
|
|
138
|
+
</p>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
) : (
|
|
142
|
+
<div className="relative w-full h-full flex items-center justify-center">
|
|
143
|
+
{/* SVG Clean Topology Network */}
|
|
144
|
+
<svg
|
|
145
|
+
viewBox="0 0 680 480"
|
|
146
|
+
className="w-full h-full max-w-[680px] max-h-[480px] select-none"
|
|
147
|
+
style={{ overflow: 'visible' }}
|
|
148
|
+
>
|
|
149
|
+
{/* Single Clean Orbital Track - Slow Gentle Spin */}
|
|
150
|
+
<circle
|
|
151
|
+
cx={center.x}
|
|
152
|
+
cy={center.y}
|
|
153
|
+
r={radius}
|
|
154
|
+
fill="none"
|
|
155
|
+
stroke={PRIMARY}
|
|
156
|
+
strokeOpacity="0.18"
|
|
157
|
+
strokeWidth="1"
|
|
158
|
+
strokeDasharray="4 6"
|
|
159
|
+
className="animate-[spin_90s_linear_infinite]"
|
|
160
|
+
/>
|
|
161
|
+
|
|
162
|
+
{/* Minimal Clean Connector Lines */}
|
|
163
|
+
{nodes.map((node) => {
|
|
164
|
+
const isSelected = node.id === selectedId
|
|
165
|
+
const isHovered = node.id === hoveredId
|
|
166
|
+
const isRunning = node.status === 'running'
|
|
167
|
+
const isFailed = node.status === 'failed' || node.status === 'killed'
|
|
168
|
+
const lineColor = isFailed ? '#ef4444' : PRIMARY
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<g key={`beam-${node.id}`}>
|
|
172
|
+
<line
|
|
173
|
+
x1={center.x}
|
|
174
|
+
y1={center.y}
|
|
175
|
+
x2={node.x}
|
|
176
|
+
y2={node.y}
|
|
177
|
+
stroke={lineColor}
|
|
178
|
+
strokeWidth={isSelected || isHovered ? 2 : 1}
|
|
179
|
+
strokeOpacity={isSelected || isHovered ? 0.9 : isFailed ? 0.6 : isRunning ? 0.6 : 0.25}
|
|
180
|
+
strokeDasharray={isRunning || isFailed ? '4 3' : undefined}
|
|
181
|
+
/>
|
|
182
|
+
|
|
183
|
+
{/* Active Minimal Pulse */}
|
|
184
|
+
{isRunning && (
|
|
185
|
+
<circle
|
|
186
|
+
r="3"
|
|
187
|
+
fill={PRIMARY}
|
|
188
|
+
stroke={WHITE}
|
|
189
|
+
strokeWidth="0.8"
|
|
190
|
+
>
|
|
191
|
+
<animateMotion
|
|
192
|
+
path={`M ${center.x} ${center.y} L ${node.x} ${node.y}`}
|
|
193
|
+
dur="1.8s"
|
|
194
|
+
repeatCount="indefinite"
|
|
195
|
+
/>
|
|
196
|
+
</circle>
|
|
197
|
+
)}
|
|
198
|
+
</g>
|
|
199
|
+
)
|
|
200
|
+
})}
|
|
201
|
+
|
|
202
|
+
{/* Center Node: Mark (Lead Agent) */}
|
|
203
|
+
<g transform={`translate(${center.x}, ${center.y})`} className="cursor-pointer">
|
|
204
|
+
{/* Subtle Ambient Breath Ring */}
|
|
205
|
+
<circle
|
|
206
|
+
r="34"
|
|
207
|
+
fill={PRIMARY}
|
|
208
|
+
fillOpacity="0.12"
|
|
209
|
+
className="animate-pulse"
|
|
210
|
+
/>
|
|
211
|
+
|
|
212
|
+
{/* Node Core */}
|
|
213
|
+
<circle
|
|
214
|
+
r="26"
|
|
215
|
+
fill={PRIMARY}
|
|
216
|
+
stroke={WHITE}
|
|
217
|
+
strokeWidth="2"
|
|
218
|
+
/>
|
|
219
|
+
<foreignObject x="-16" y="-16" width="32" height="32">
|
|
220
|
+
<div className="w-full h-full flex items-center justify-center text-white">
|
|
221
|
+
<Brain className="w-5 h-5" />
|
|
222
|
+
</div>
|
|
223
|
+
</foreignObject>
|
|
224
|
+
|
|
225
|
+
{/* Minimal Text Label */}
|
|
226
|
+
<text
|
|
227
|
+
y="42"
|
|
228
|
+
textAnchor="middle"
|
|
229
|
+
fill={WHITE}
|
|
230
|
+
className="text-[10px] font-semibold tracking-wider font-mono"
|
|
231
|
+
>
|
|
232
|
+
MARK (LEAD)
|
|
233
|
+
</text>
|
|
234
|
+
</g>
|
|
235
|
+
|
|
236
|
+
{/* Satellite Nodes: Sub-Agents */}
|
|
237
|
+
{nodes.map((node) => {
|
|
238
|
+
const isSelected = node.id === selectedId
|
|
239
|
+
const isHovered = node.id === hoveredId
|
|
240
|
+
const isRunning = node.status === 'running'
|
|
241
|
+
const isFailed = node.status === 'failed' || node.status === 'killed'
|
|
242
|
+
const nodeColor = isFailed ? '#ef4444' : PRIMARY
|
|
243
|
+
|
|
244
|
+
return (
|
|
245
|
+
<g
|
|
246
|
+
key={`node-${node.id}`}
|
|
247
|
+
transform={`translate(${node.x}, ${node.y})`}
|
|
248
|
+
className="cursor-pointer"
|
|
249
|
+
onClick={() => onSelectAgent(node.id)}
|
|
250
|
+
onMouseEnter={() => setHoveredId(node.id)}
|
|
251
|
+
onMouseLeave={() => setHoveredId(null)}
|
|
252
|
+
>
|
|
253
|
+
{/* Invisible Hitbox */}
|
|
254
|
+
<circle r="30" fill="transparent" />
|
|
255
|
+
|
|
256
|
+
{/* Active/Hover Clean Ring with Gentle Spin */}
|
|
257
|
+
{(isSelected || isHovered) && (
|
|
258
|
+
<circle
|
|
259
|
+
r="25"
|
|
260
|
+
fill="none"
|
|
261
|
+
stroke={nodeColor}
|
|
262
|
+
strokeWidth="1.5"
|
|
263
|
+
strokeDasharray="3 3"
|
|
264
|
+
className="animate-[spin_10s_linear_infinite]"
|
|
265
|
+
/>
|
|
266
|
+
)}
|
|
267
|
+
|
|
268
|
+
{/* Node Core Body */}
|
|
269
|
+
<circle
|
|
270
|
+
r={isSelected || isHovered ? 20 : 18}
|
|
271
|
+
fill={nodeColor}
|
|
272
|
+
stroke={WHITE}
|
|
273
|
+
strokeWidth={isSelected || isHovered ? 2 : 1.2}
|
|
274
|
+
className="transition-all duration-150"
|
|
275
|
+
/>
|
|
276
|
+
|
|
277
|
+
{/* Icon Inside Node */}
|
|
278
|
+
<foreignObject x="-11" y="-11" width="22" height="22">
|
|
279
|
+
<div className="w-full h-full flex items-center justify-center text-white">
|
|
280
|
+
{isFailed ? (
|
|
281
|
+
<AlertTriangle className="w-3.5 h-3.5 text-white" />
|
|
282
|
+
) : isRunning ? (
|
|
283
|
+
<Activity className="w-3.5 h-3.5 animate-spin" />
|
|
284
|
+
) : node.status === 'idle' ? (
|
|
285
|
+
<Bot className="w-3.5 h-3.5 text-white" />
|
|
286
|
+
) : (
|
|
287
|
+
<CheckCircle2 className="w-3.5 h-3.5 text-white" />
|
|
288
|
+
)}
|
|
289
|
+
</div>
|
|
290
|
+
</foreignObject>
|
|
291
|
+
|
|
292
|
+
{/* Clean Sub-agent Name Label */}
|
|
293
|
+
<text
|
|
294
|
+
y="34"
|
|
295
|
+
textAnchor="middle"
|
|
296
|
+
fill={isFailed ? '#fca5a5' : WHITE}
|
|
297
|
+
className="text-[9px] font-medium tracking-tight"
|
|
298
|
+
>
|
|
299
|
+
{node.name.length > 14 ? node.name.slice(0, 12) + '..' : node.name}
|
|
300
|
+
</text>
|
|
301
|
+
</g>
|
|
302
|
+
)
|
|
303
|
+
})}
|
|
304
|
+
</svg>
|
|
305
|
+
</div>
|
|
306
|
+
)}
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
{/* Right Telemetry / Inspector Drawer */}
|
|
310
|
+
<div className="w-full md:w-80 flex flex-col bg-base-200/50 rounded-2xl border border-base-content/10 overflow-hidden flex-none backdrop-blur-md">
|
|
311
|
+
<div className="p-3.5 border-b border-base-content/10 flex items-center justify-between bg-base-300/40">
|
|
312
|
+
<div className="flex items-center gap-2">
|
|
313
|
+
<Terminal className="w-4 h-4 text-primary" />
|
|
314
|
+
<span className="font-semibold text-xs tracking-wide">Inspeksi Agen</span>
|
|
315
|
+
</div>
|
|
316
|
+
{selectedAgent && (
|
|
317
|
+
<button
|
|
318
|
+
type="button"
|
|
319
|
+
onClick={() => onOpenIntercom(selectedAgent.id)}
|
|
320
|
+
className="btn btn-ghost btn-xs gap-1 text-[10px] text-primary hover:bg-primary/10"
|
|
321
|
+
title="Buka Chat Intercom Penuh"
|
|
322
|
+
>
|
|
323
|
+
Intercom <ExternalLink className="w-3 h-3" />
|
|
324
|
+
</button>
|
|
325
|
+
)}
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
{selectedAgent ? (
|
|
329
|
+
<div className="flex-1 flex flex-col overflow-y-auto p-3.5 space-y-3.5 custom-scrollbar">
|
|
330
|
+
{/* Agent Header Card */}
|
|
331
|
+
<div className="p-3 bg-base-100/60 rounded-xl border border-base-content/10 space-y-2">
|
|
332
|
+
<div className="flex items-center justify-between gap-2">
|
|
333
|
+
<div className="flex items-center gap-2 min-w-0">
|
|
334
|
+
<div className="w-7 h-7 rounded-lg bg-primary/15 border border-primary/30 text-primary flex items-center justify-center font-bold text-xs flex-none">
|
|
335
|
+
{selectedAgent.name.slice(0, 2).toUpperCase()}
|
|
336
|
+
</div>
|
|
337
|
+
<div className="min-w-0">
|
|
338
|
+
<h4 className="font-semibold text-xs truncate">{selectedAgent.name}</h4>
|
|
339
|
+
<p className="text-[10px] opacity-60 truncate font-mono">{selectedAgent.role}</p>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
<div className="flex-none">
|
|
343
|
+
{selectedAgent.status === 'running' ? (
|
|
344
|
+
<span className="badge badge-primary badge-xs gap-1 font-mono text-[9px]">
|
|
345
|
+
<span className="w-1.5 h-1.5 rounded-full bg-primary-content animate-ping" />
|
|
346
|
+
RUNNING
|
|
347
|
+
</span>
|
|
348
|
+
) : selectedAgent.status === 'idle' ? (
|
|
349
|
+
<span className="badge badge-primary badge-outline badge-xs font-mono text-[9px]">
|
|
350
|
+
IDLE / STANDBY
|
|
351
|
+
</span>
|
|
352
|
+
) : selectedAgent.status === 'failed' || selectedAgent.status === 'killed' ? (
|
|
353
|
+
<span className="badge badge-error badge-xs font-mono text-[9px]">FAILED</span>
|
|
354
|
+
) : (
|
|
355
|
+
<span className="badge badge-primary badge-outline badge-xs font-mono text-[9px]">COMPLETED</span>
|
|
356
|
+
)}
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<div className="text-[10px] text-base-content/70 font-mono bg-base-200/60 p-2.5 rounded-lg border border-base-content/5">
|
|
361
|
+
<span className="text-primary font-bold block text-[9px] mb-0.5 uppercase tracking-wider">Misi / Goal:</span>
|
|
362
|
+
<p className="line-clamp-2 leading-relaxed">{selectedAgent.goal}</p>
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
|
|
366
|
+
{/* Live Progress / Output Preview */}
|
|
367
|
+
<div className="flex-1 bg-base-100/40 rounded-xl border border-base-content/10 p-3 space-y-2 flex flex-col">
|
|
368
|
+
<div className="flex items-center justify-between text-[10px] font-semibold text-base-content/70">
|
|
369
|
+
<span className="flex items-center gap-1.5">
|
|
370
|
+
<Sparkles className="w-3.5 h-3.5 text-primary" /> Laporan Terkini:
|
|
371
|
+
</span>
|
|
372
|
+
<span className="font-mono text-[9px]">Turn #{selectedAgent.turnCount || 0}</span>
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<div className="flex-1 bg-base-200/50 rounded-lg p-2.5 text-[11px] font-mono leading-relaxed overflow-y-auto max-h-44 text-base-content/90 border border-base-content/5">
|
|
376
|
+
{selectedAgent.finalAnswer ? (
|
|
377
|
+
<p className="whitespace-pre-wrap">{selectedAgent.finalAnswer}</p>
|
|
378
|
+
) : selectedAgent.status === 'running' ? (
|
|
379
|
+
<div className="flex items-center gap-2 text-primary opacity-80 py-2">
|
|
380
|
+
<Activity className="w-3.5 h-3.5 animate-spin" />
|
|
381
|
+
<span>Sedang memproses langkah...</span>
|
|
382
|
+
</div>
|
|
383
|
+
) : (
|
|
384
|
+
<span className="opacity-40 italic">Belum ada output yang tercatat.</span>
|
|
385
|
+
)}
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
|
|
389
|
+
{/* Quick Mentoring / Correction Dispatch */}
|
|
390
|
+
<form onSubmit={handleQuickSend} className="space-y-1.5 pt-1">
|
|
391
|
+
<label className="text-[10px] font-semibold text-base-content/70 flex items-center gap-1">
|
|
392
|
+
<Send className="w-2.5 h-2.5 text-primary" /> Kirim Arahan Cepat (Lead Agent):
|
|
393
|
+
</label>
|
|
394
|
+
<div className="flex gap-1.5">
|
|
395
|
+
<input
|
|
396
|
+
type="text"
|
|
397
|
+
placeholder="Ketik instruksi koreksi..."
|
|
398
|
+
value={quickInput}
|
|
399
|
+
onChange={(e) => setQuickInput(e.target.value)}
|
|
400
|
+
className="input input-xs input-bordered flex-1 rounded-lg text-[11px] bg-base-100/60 focus:border-primary"
|
|
401
|
+
disabled={isSending}
|
|
402
|
+
/>
|
|
403
|
+
<button
|
|
404
|
+
type="submit"
|
|
405
|
+
disabled={!quickInput.trim() || isSending}
|
|
406
|
+
className="btn btn-primary btn-xs rounded-lg px-2.5"
|
|
407
|
+
title="Kirim Pesan ke Sub-Agent"
|
|
408
|
+
>
|
|
409
|
+
{isSending ? <span className="loading loading-spinner loading-xs" /> : <Send className="w-3 h-3" />}
|
|
410
|
+
</button>
|
|
411
|
+
</div>
|
|
412
|
+
</form>
|
|
413
|
+
</div>
|
|
414
|
+
) : (
|
|
415
|
+
<div className="flex-1 flex flex-col items-center justify-center p-6 text-center text-base-content/40 space-y-2">
|
|
416
|
+
<Bot className="w-8 h-8 stroke-[1.2] opacity-40 text-primary" />
|
|
417
|
+
<p className="text-xs">Klik salah satu node sub-agent pada diagram di samping untuk memeriksa status & memberikan arahan langsung.</p>
|
|
418
|
+
</div>
|
|
419
|
+
)}
|
|
420
|
+
</div>
|
|
421
|
+
</div>
|
|
422
|
+
)
|
|
423
|
+
}
|