@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,758 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import os from 'os'
|
|
3
|
+
import fs from 'fs'
|
|
4
|
+
import Database from 'better-sqlite3'
|
|
5
|
+
|
|
6
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'mark-agent')
|
|
7
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
8
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true })
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const DB_PATH = path.join(CONFIG_DIR, 'mark.db')
|
|
12
|
+
|
|
13
|
+
// Inisialisasi Database SQLite
|
|
14
|
+
export const sqlite = new Database(DB_PATH)
|
|
15
|
+
|
|
16
|
+
// Optimasi performa SQLite (WAL mode, memory temp store, normal sync)
|
|
17
|
+
sqlite.pragma('journal_mode = WAL')
|
|
18
|
+
sqlite.pragma('synchronous = NORMAL')
|
|
19
|
+
sqlite.pragma('temp_store = MEMORY')
|
|
20
|
+
|
|
21
|
+
// Buat Skema Tabel
|
|
22
|
+
sqlite.exec(`
|
|
23
|
+
-- 1. Configuration Store
|
|
24
|
+
CREATE TABLE IF NOT EXISTS config (
|
|
25
|
+
id TEXT PRIMARY KEY,
|
|
26
|
+
data TEXT NOT NULL,
|
|
27
|
+
updated_at INTEGER
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- 2. Cognitive Memory Store (MMS)
|
|
31
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
type TEXT DEFAULT 'notes',
|
|
34
|
+
summary TEXT DEFAULT '',
|
|
35
|
+
memory TEXT NOT NULL,
|
|
36
|
+
vector TEXT,
|
|
37
|
+
confidence REAL DEFAULT 1.0,
|
|
38
|
+
created_at INTEGER NOT NULL,
|
|
39
|
+
updated_at INTEGER
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
-- 3. Sessions & Threads
|
|
43
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
44
|
+
id TEXT PRIMARY KEY,
|
|
45
|
+
title TEXT DEFAULT 'New Session',
|
|
46
|
+
data TEXT,
|
|
47
|
+
workspace_root TEXT,
|
|
48
|
+
is_auto_mode INTEGER DEFAULT 0,
|
|
49
|
+
timestamp INTEGER NOT NULL,
|
|
50
|
+
created_at INTEGER NOT NULL,
|
|
51
|
+
updated_at INTEGER
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
-- 4. Chat Turns / History
|
|
55
|
+
CREATE TABLE IF NOT EXISTS chat_turns (
|
|
56
|
+
id TEXT PRIMARY KEY,
|
|
57
|
+
session_id TEXT DEFAULT '1',
|
|
58
|
+
session_title TEXT DEFAULT '',
|
|
59
|
+
user_text TEXT NOT NULL,
|
|
60
|
+
ai_text TEXT NOT NULL,
|
|
61
|
+
combined_text TEXT,
|
|
62
|
+
vector TEXT,
|
|
63
|
+
timestamp INTEGER,
|
|
64
|
+
created_at INTEGER,
|
|
65
|
+
updated_at INTEGER
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
-- 5. Chat Archives
|
|
69
|
+
CREATE TABLE IF NOT EXISTS chat_archives (
|
|
70
|
+
id TEXT PRIMARY KEY,
|
|
71
|
+
summary TEXT NOT NULL,
|
|
72
|
+
topic TEXT DEFAULT '',
|
|
73
|
+
vector TEXT,
|
|
74
|
+
timestamp INTEGER NOT NULL
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
-- 6. Knowledge Documents (RAG)
|
|
78
|
+
CREATE TABLE IF NOT EXISTS documents (
|
|
79
|
+
id TEXT PRIMARY KEY,
|
|
80
|
+
doc_name TEXT NOT NULL,
|
|
81
|
+
chunk_index INTEGER DEFAULT 0,
|
|
82
|
+
content TEXT NOT NULL,
|
|
83
|
+
vector TEXT,
|
|
84
|
+
timestamp INTEGER NOT NULL
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
-- 7. Relational Growth 4D
|
|
88
|
+
CREATE TABLE IF NOT EXISTS relationships (
|
|
89
|
+
user_id TEXT PRIMARY KEY,
|
|
90
|
+
warmth REAL DEFAULT 0.5,
|
|
91
|
+
sarcasm_level REAL DEFAULT 0.5,
|
|
92
|
+
trust REAL DEFAULT 0.5,
|
|
93
|
+
energy REAL DEFAULT 0.5,
|
|
94
|
+
obedience REAL DEFAULT 0.8,
|
|
95
|
+
reasoning TEXT,
|
|
96
|
+
new_relational_memory TEXT,
|
|
97
|
+
last_evaluation INTEGER,
|
|
98
|
+
eval_count INTEGER DEFAULT 0,
|
|
99
|
+
last_chat_index INTEGER DEFAULT 0
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
-- 8. Sub-Agents
|
|
103
|
+
CREATE TABLE IF NOT EXISTS subagents (
|
|
104
|
+
id TEXT PRIMARY KEY,
|
|
105
|
+
name TEXT NOT NULL,
|
|
106
|
+
role TEXT DEFAULT '',
|
|
107
|
+
goal TEXT DEFAULT '',
|
|
108
|
+
allowed_tools TEXT,
|
|
109
|
+
status TEXT DEFAULT 'running',
|
|
110
|
+
turn_count INTEGER DEFAULT 0,
|
|
111
|
+
parent_session_id TEXT DEFAULT '1',
|
|
112
|
+
parent_session_title TEXT DEFAULT '',
|
|
113
|
+
final_answer TEXT,
|
|
114
|
+
created_at INTEGER NOT NULL,
|
|
115
|
+
updated_at INTEGER
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
-- 9. Sub-Agent Messages
|
|
119
|
+
CREATE TABLE IF NOT EXISTS subagent_messages (
|
|
120
|
+
id TEXT PRIMARY KEY,
|
|
121
|
+
subagent_id TEXT NOT NULL,
|
|
122
|
+
sender TEXT NOT NULL,
|
|
123
|
+
role TEXT DEFAULT 'assistant',
|
|
124
|
+
content TEXT NOT NULL,
|
|
125
|
+
thought TEXT,
|
|
126
|
+
action TEXT,
|
|
127
|
+
tool_calls TEXT,
|
|
128
|
+
tool_call_id TEXT,
|
|
129
|
+
name TEXT,
|
|
130
|
+
timestamp INTEGER NOT NULL
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
-- 10. Learned Skills
|
|
134
|
+
CREATE TABLE IF NOT EXISTS learned_skills (
|
|
135
|
+
id TEXT PRIMARY KEY,
|
|
136
|
+
name TEXT NOT NULL,
|
|
137
|
+
description TEXT DEFAULT '',
|
|
138
|
+
content TEXT,
|
|
139
|
+
created_at INTEGER NOT NULL,
|
|
140
|
+
updated_at INTEGER
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
-- 11. Agent Tasks
|
|
144
|
+
CREATE TABLE IF NOT EXISTS agent_tasks (
|
|
145
|
+
id TEXT PRIMARY KEY,
|
|
146
|
+
status TEXT DEFAULT 'pending',
|
|
147
|
+
mode TEXT DEFAULT 'ephemeral',
|
|
148
|
+
title TEXT DEFAULT '',
|
|
149
|
+
objective TEXT DEFAULT '',
|
|
150
|
+
current_step_index INTEGER DEFAULT 0,
|
|
151
|
+
active_step_id TEXT,
|
|
152
|
+
constraints TEXT,
|
|
153
|
+
context_summary TEXT,
|
|
154
|
+
artifact_root TEXT,
|
|
155
|
+
retry_count INTEGER DEFAULT 0,
|
|
156
|
+
max_retries INTEGER DEFAULT 2,
|
|
157
|
+
created_at INTEGER NOT NULL,
|
|
158
|
+
updated_at INTEGER,
|
|
159
|
+
completed_at INTEGER,
|
|
160
|
+
error TEXT
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
-- 12. Agent Task Steps
|
|
164
|
+
CREATE TABLE IF NOT EXISTS agent_task_steps (
|
|
165
|
+
id TEXT PRIMARY KEY,
|
|
166
|
+
task_id TEXT NOT NULL,
|
|
167
|
+
step_index INTEGER DEFAULT 0,
|
|
168
|
+
title TEXT DEFAULT '',
|
|
169
|
+
objective TEXT DEFAULT '',
|
|
170
|
+
deliverable TEXT DEFAULT '',
|
|
171
|
+
acceptance_criteria TEXT,
|
|
172
|
+
status TEXT DEFAULT 'pending',
|
|
173
|
+
input_summary TEXT,
|
|
174
|
+
output_summary TEXT,
|
|
175
|
+
artifact_path TEXT,
|
|
176
|
+
validation TEXT,
|
|
177
|
+
content_hash TEXT,
|
|
178
|
+
attempts INTEGER DEFAULT 0,
|
|
179
|
+
started_at INTEGER,
|
|
180
|
+
completed_at INTEGER,
|
|
181
|
+
updated_at INTEGER,
|
|
182
|
+
error TEXT
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
-- 13. Session Compact (Metadata Kompaksi Konteks)
|
|
186
|
+
CREATE TABLE IF NOT EXISTS session_compact (
|
|
187
|
+
session_id TEXT PRIMARY KEY,
|
|
188
|
+
summary_block TEXT,
|
|
189
|
+
last_compacted_message_id TEXT,
|
|
190
|
+
last_compacted_at INTEGER
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
-- Indeks untuk pencarian cepat
|
|
194
|
+
CREATE INDEX IF NOT EXISTS idx_chat_turns_session ON chat_turns(session_id);
|
|
195
|
+
CREATE INDEX IF NOT EXISTS idx_chat_turns_timestamp ON chat_turns(timestamp);
|
|
196
|
+
CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
|
|
197
|
+
CREATE INDEX IF NOT EXISTS idx_subagent_messages_subagent ON subagent_messages(subagent_id);
|
|
198
|
+
CREATE INDEX IF NOT EXISTS idx_agent_task_steps_task ON agent_task_steps(task_id);
|
|
199
|
+
`)
|
|
200
|
+
|
|
201
|
+
// Helper migrasi kolom otomatis jika tabel SQLite sudah ada dari versi sebelumnya
|
|
202
|
+
function ensureTableColumns(tableName, requiredColumns) {
|
|
203
|
+
try {
|
|
204
|
+
const existingCols = sqlite
|
|
205
|
+
.prepare(`PRAGMA table_info(${tableName})`)
|
|
206
|
+
.all()
|
|
207
|
+
.map((c) => c.name)
|
|
208
|
+
for (const [colName, colType] of Object.entries(requiredColumns)) {
|
|
209
|
+
if (!existingCols.includes(colName)) {
|
|
210
|
+
sqlite.exec(`ALTER TABLE ${tableName} ADD COLUMN ${colName} ${colType}`)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} catch (err) {
|
|
214
|
+
console.warn(`[DB Store] Auto-migration error on ${tableName}:`, err.message)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
ensureTableColumns('sessions', {
|
|
219
|
+
workspace_root: 'TEXT',
|
|
220
|
+
is_auto_mode: 'INTEGER DEFAULT 0'
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
// Migrasi satu kali jika ada data di kolom legacy workspace
|
|
224
|
+
try {
|
|
225
|
+
sqlite.exec(`
|
|
226
|
+
UPDATE sessions
|
|
227
|
+
SET workspace_root = workspace
|
|
228
|
+
WHERE (workspace_root IS NULL OR workspace_root = '') AND workspace IS NOT NULL AND workspace != ''
|
|
229
|
+
`)
|
|
230
|
+
} catch (err) {
|
|
231
|
+
void err
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
ensureTableColumns('chat_turns', {
|
|
235
|
+
created_at: 'INTEGER',
|
|
236
|
+
updated_at: 'INTEGER'
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
ensureTableColumns('relationships', {
|
|
240
|
+
reasoning: 'TEXT',
|
|
241
|
+
new_relational_memory: 'TEXT',
|
|
242
|
+
last_chat_index: 'INTEGER DEFAULT 0'
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
ensureTableColumns('subagents', {
|
|
246
|
+
allowed_tools: 'TEXT',
|
|
247
|
+
final_answer: 'TEXT',
|
|
248
|
+
parent_session_id: "TEXT DEFAULT '1'",
|
|
249
|
+
parent_session_title: 'TEXT'
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
ensureTableColumns('subagent_messages', {
|
|
253
|
+
thought: 'TEXT',
|
|
254
|
+
action: 'TEXT',
|
|
255
|
+
tool_calls: 'TEXT',
|
|
256
|
+
tool_call_id: 'TEXT',
|
|
257
|
+
name: 'TEXT'
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
ensureTableColumns('agent_tasks', {
|
|
261
|
+
current_step_index: 'INTEGER DEFAULT 0',
|
|
262
|
+
active_step_id: 'TEXT',
|
|
263
|
+
constraints: 'TEXT',
|
|
264
|
+
context_summary: 'TEXT',
|
|
265
|
+
artifact_root: 'TEXT',
|
|
266
|
+
retry_count: 'INTEGER DEFAULT 0',
|
|
267
|
+
max_retries: 'INTEGER DEFAULT 2',
|
|
268
|
+
completed_at: 'INTEGER',
|
|
269
|
+
error: 'TEXT'
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
ensureTableColumns('agent_task_steps', {
|
|
273
|
+
objective: 'TEXT',
|
|
274
|
+
deliverable: 'TEXT',
|
|
275
|
+
acceptance_criteria: 'TEXT',
|
|
276
|
+
input_summary: 'TEXT',
|
|
277
|
+
output_summary: 'TEXT',
|
|
278
|
+
artifact_path: 'TEXT',
|
|
279
|
+
validation: 'TEXT',
|
|
280
|
+
content_hash: 'TEXT',
|
|
281
|
+
attempts: 'INTEGER DEFAULT 0',
|
|
282
|
+
started_at: 'INTEGER',
|
|
283
|
+
completed_at: 'INTEGER',
|
|
284
|
+
error: 'TEXT'
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
ensureTableColumns('session_compact', {
|
|
288
|
+
summary_block: 'TEXT',
|
|
289
|
+
last_compacted_message_id: 'TEXT',
|
|
290
|
+
last_compacted_at: 'INTEGER',
|
|
291
|
+
total_tokens: 'INTEGER DEFAULT 0'
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Normalisasi ID SQLite: Memastikan ID selalu berupa string bersih tanpa pecahan desimal (.0).
|
|
296
|
+
* Menstandarkan seluruh ID (primary key, foreign key, session_id) ke format string tunggal yang seragam.
|
|
297
|
+
*/
|
|
298
|
+
export function normalizeSqliteId(id) {
|
|
299
|
+
if (id === null || id === undefined) return ''
|
|
300
|
+
let clean = String(id).trim()
|
|
301
|
+
if (clean.endsWith('.0')) {
|
|
302
|
+
clean = clean.slice(0, -2)
|
|
303
|
+
}
|
|
304
|
+
clean = clean.replace(/^(\d+)\.0+$/, '$1')
|
|
305
|
+
if (clean === '1' || clean === '1.0' || clean === '1.00') {
|
|
306
|
+
clean = '1'
|
|
307
|
+
}
|
|
308
|
+
return clean
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Generic Table Helper untuk menyediakan API CRUD fleksibel
|
|
313
|
+
*/
|
|
314
|
+
class SqliteTable {
|
|
315
|
+
constructor(tableName, idCol = 'id') {
|
|
316
|
+
this.tableName = tableName
|
|
317
|
+
this.idCol = idCol
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
_parseJsonFields(row) {
|
|
321
|
+
if (!row) return null
|
|
322
|
+
const res = { ...row }
|
|
323
|
+
|
|
324
|
+
// Normalisasi otomatis snake_case ke camelCase untuk konsistensi di frontend
|
|
325
|
+
for (const key of Object.keys(row)) {
|
|
326
|
+
if (key.includes('_')) {
|
|
327
|
+
const camelKey = this._toCamel(key)
|
|
328
|
+
if (res[camelKey] === undefined) {
|
|
329
|
+
res[camelKey] = row[key]
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Normalisasi khusus step_index agar kompatibel timbal balik di frontend (index & stepIndex)
|
|
335
|
+
if (this.tableName === 'agent_task_steps') {
|
|
336
|
+
if (res.step_index !== undefined) {
|
|
337
|
+
if (res.index === undefined) res.index = res.step_index
|
|
338
|
+
if (res.stepIndex === undefined) res.stepIndex = res.step_index
|
|
339
|
+
}
|
|
340
|
+
if (res.task_id !== undefined && res.taskId === undefined) {
|
|
341
|
+
res.taskId = res.task_id
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Normalisasi khusus agent_tasks
|
|
346
|
+
if (this.tableName === 'agent_tasks') {
|
|
347
|
+
if (res.active_step_id !== undefined && res.activeStepId === undefined) {
|
|
348
|
+
res.activeStepId = res.active_step_id
|
|
349
|
+
}
|
|
350
|
+
if (res.current_step_index !== undefined && res.currentStepIndex === undefined) {
|
|
351
|
+
res.currentStepIndex = res.current_step_index
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Normalisasi khusus sessions: jadikan satu variabel workspaceRoot
|
|
356
|
+
if (this.tableName === 'sessions') {
|
|
357
|
+
res.workspaceRoot = res.workspace_root || res.workspaceRoot || null
|
|
358
|
+
delete res.workspace
|
|
359
|
+
delete res.workspace_root
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
for (const key of Object.keys(res)) {
|
|
363
|
+
if (typeof res[key] === 'string') {
|
|
364
|
+
const str = res[key].trim()
|
|
365
|
+
if (
|
|
366
|
+
(str.startsWith('{') && str.endsWith('}')) ||
|
|
367
|
+
(str.startsWith('[') && str.endsWith(']'))
|
|
368
|
+
) {
|
|
369
|
+
try {
|
|
370
|
+
res[key] = JSON.parse(str)
|
|
371
|
+
} catch (err) {
|
|
372
|
+
void err
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return res
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
_serializeJsonFields(obj) {
|
|
381
|
+
const res = { ...obj }
|
|
382
|
+
for (const key of Object.keys(res)) {
|
|
383
|
+
if (typeof res[key] === 'object' && res[key] !== null) {
|
|
384
|
+
res[key] = JSON.stringify(res[key])
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return res
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
getAll() {
|
|
391
|
+
const rows = sqlite.prepare(`SELECT * FROM ${this.tableName} ORDER BY rowid ASC`).all()
|
|
392
|
+
return rows.map((r) => this._parseJsonFields(r))
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
getById(id) {
|
|
396
|
+
const cleanId = normalizeSqliteId(id)
|
|
397
|
+
const row = sqlite
|
|
398
|
+
.prepare(`SELECT * FROM ${this.tableName} WHERE ${this.idCol} = ?`)
|
|
399
|
+
.get(cleanId)
|
|
400
|
+
return this._parseJsonFields(row)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
insert(item) {
|
|
404
|
+
const raw = { ...item }
|
|
405
|
+
// Normalisasi alias primary key lama dari Dexie (pairId -> id)
|
|
406
|
+
let id =
|
|
407
|
+
raw[this.idCol] !== undefined && raw[this.idCol] !== null
|
|
408
|
+
? raw[this.idCol]
|
|
409
|
+
: raw.id !== undefined && raw.id !== null
|
|
410
|
+
? raw.id
|
|
411
|
+
: raw.pairId ||
|
|
412
|
+
raw.userId ||
|
|
413
|
+
raw.sessionId ||
|
|
414
|
+
raw.session_id ||
|
|
415
|
+
`id_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`
|
|
416
|
+
|
|
417
|
+
const cleanId = normalizeSqliteId(id)
|
|
418
|
+
|
|
419
|
+
if (this.idCol !== 'id') {
|
|
420
|
+
delete raw.id
|
|
421
|
+
}
|
|
422
|
+
delete raw.pairId // Hapus key lama agar tidak mencoba insert ke kolom yang tidak ada
|
|
423
|
+
|
|
424
|
+
if (raw.sessionId !== undefined && raw.sessionId !== null) {
|
|
425
|
+
raw.sessionId = normalizeSqliteId(raw.sessionId)
|
|
426
|
+
}
|
|
427
|
+
if (raw.session_id !== undefined && raw.session_id !== null) {
|
|
428
|
+
raw.session_id = normalizeSqliteId(raw.session_id)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Penanganan khusus untuk tabel config jika item berupa objek key-value langsung (bukan { id, data })
|
|
432
|
+
if (this.tableName === 'config' && raw.data === undefined) {
|
|
433
|
+
raw.data = { ...raw }
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Normalisasi index ke step_index untuk tabel agent_task_steps
|
|
437
|
+
if (this.tableName === 'agent_task_steps') {
|
|
438
|
+
if (raw.index !== undefined && raw.step_index === undefined && raw.stepIndex === undefined) {
|
|
439
|
+
raw.step_index = raw.index
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Normalisasi khusus sessions: jadikan satu variabel workspaceRoot
|
|
444
|
+
if (this.tableName === 'sessions') {
|
|
445
|
+
raw.workspaceRoot = raw.workspaceRoot || null
|
|
446
|
+
delete raw.workspace
|
|
447
|
+
delete raw.workspace_root
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const record = {
|
|
451
|
+
timestamp: raw.timestamp || raw.createdAt || Date.now(),
|
|
452
|
+
createdAt: raw.createdAt || raw.timestamp || Date.now(),
|
|
453
|
+
updatedAt: raw.updatedAt || Date.now(),
|
|
454
|
+
...raw,
|
|
455
|
+
id: cleanId,
|
|
456
|
+
[this.idCol]: cleanId
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const serialized = this._serializeJsonFields(record)
|
|
460
|
+
// Filter hanya field yang ada di skema kolom tabel (gunakan Map untuk mencegah duplikasi kolom snake/camel)
|
|
461
|
+
const tableCols = sqlite
|
|
462
|
+
.prepare(`PRAGMA table_info(${this.tableName})`)
|
|
463
|
+
.all()
|
|
464
|
+
.map((c) => c.name)
|
|
465
|
+
|
|
466
|
+
const colMap = new Map()
|
|
467
|
+
for (const [k, v] of Object.entries(serialized)) {
|
|
468
|
+
const col = this._toSnake(k)
|
|
469
|
+
if (tableCols.includes(col)) {
|
|
470
|
+
if (colMap.has(col) && k !== col) {
|
|
471
|
+
const currentVal = colMap.get(col)
|
|
472
|
+
if (currentVal !== null && currentVal !== undefined && currentVal !== '') {
|
|
473
|
+
continue
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
colMap.set(col, v)
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (tableCols.includes(this.idCol)) {
|
|
480
|
+
colMap.set(this.idCol, cleanId)
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const keys = Array.from(colMap.keys())
|
|
484
|
+
const placeholders = keys.map(() => '?').join(', ')
|
|
485
|
+
const values = Array.from(colMap.values())
|
|
486
|
+
|
|
487
|
+
const stmt = sqlite.prepare(`
|
|
488
|
+
INSERT OR REPLACE INTO ${this.tableName} (${keys.join(', ')})
|
|
489
|
+
VALUES (${placeholders})
|
|
490
|
+
`)
|
|
491
|
+
|
|
492
|
+
stmt.run(...values)
|
|
493
|
+
return record
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
insertBatch(items) {
|
|
497
|
+
if (!Array.isArray(items) || items.length === 0) return []
|
|
498
|
+
const insertMany = sqlite.transaction((rows) => {
|
|
499
|
+
const results = []
|
|
500
|
+
for (const row of rows) {
|
|
501
|
+
results.push(this.insert(row))
|
|
502
|
+
}
|
|
503
|
+
return results
|
|
504
|
+
})
|
|
505
|
+
return insertMany(items)
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
update(id, updates) {
|
|
509
|
+
const existing = this.getById(id)
|
|
510
|
+
if (!existing) return null
|
|
511
|
+
|
|
512
|
+
const normalizedUpdates = { ...updates }
|
|
513
|
+
for (const [k, v] of Object.entries(updates)) {
|
|
514
|
+
const snake = this._toSnake(k)
|
|
515
|
+
const camel = this._toCamel(k)
|
|
516
|
+
normalizedUpdates[snake] = v
|
|
517
|
+
normalizedUpdates[camel] = v
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const updated = { ...existing, ...normalizedUpdates, updatedAt: Date.now() }
|
|
521
|
+
this.insert(updated)
|
|
522
|
+
return this.getById(id)
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
delete(id) {
|
|
526
|
+
const cleanId = normalizeSqliteId(id)
|
|
527
|
+
const info = sqlite
|
|
528
|
+
.prepare(`DELETE FROM ${this.tableName} WHERE ${this.idCol} = ?`)
|
|
529
|
+
.run(cleanId)
|
|
530
|
+
return info.changes > 0
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
clear() {
|
|
534
|
+
sqlite.prepare(`DELETE FROM ${this.tableName}`).run()
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
count() {
|
|
538
|
+
const res = sqlite.prepare(`SELECT COUNT(*) as count FROM ${this.tableName}`).get()
|
|
539
|
+
return res?.count || 0
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
_toCamel(str) {
|
|
543
|
+
return str.replace(/_([a-z0-9])/g, (_, letter) => letter.toUpperCase())
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
_toSnake(str) {
|
|
547
|
+
// Normalisasi properti umum ke skema SQLite
|
|
548
|
+
const map = {
|
|
549
|
+
sessionId: 'session_id',
|
|
550
|
+
sessionTitle: 'session_title',
|
|
551
|
+
userText: 'user_text',
|
|
552
|
+
aiText: 'ai_text',
|
|
553
|
+
combinedText: 'combined_text',
|
|
554
|
+
createdAt: 'created_at',
|
|
555
|
+
updatedAt: 'updated_at',
|
|
556
|
+
docName: 'doc_name',
|
|
557
|
+
chunkIndex: 'chunk_index',
|
|
558
|
+
userId: 'user_id',
|
|
559
|
+
sarcasmLevel: 'sarcasm_level',
|
|
560
|
+
lastEvaluation: 'last_evaluation',
|
|
561
|
+
evalCount: 'eval_count',
|
|
562
|
+
lastChatIndex: 'last_chat_index',
|
|
563
|
+
turnCount: 'turn_count',
|
|
564
|
+
parentSessionId: 'parent_session_id',
|
|
565
|
+
subagentId: 'subagent_id',
|
|
566
|
+
toolCalls: 'tool_calls',
|
|
567
|
+
toolCallId: 'tool_call_id',
|
|
568
|
+
taskId: 'task_id',
|
|
569
|
+
stepIndex: 'step_index',
|
|
570
|
+
activeStepId: 'active_step_id',
|
|
571
|
+
currentStepIndex: 'current_step_index',
|
|
572
|
+
artifactRoot: 'artifact_root',
|
|
573
|
+
contextSummary: 'context_summary',
|
|
574
|
+
retryCount: 'retry_count',
|
|
575
|
+
maxRetries: 'max_retries',
|
|
576
|
+
completedAt: 'completed_at',
|
|
577
|
+
artifactPath: 'artifact_path',
|
|
578
|
+
contentHash: 'content_hash',
|
|
579
|
+
inputSummary: 'input_summary',
|
|
580
|
+
outputSummary: 'output_summary',
|
|
581
|
+
startedAt: 'started_at',
|
|
582
|
+
acceptanceCriteria: 'acceptance_criteria'
|
|
583
|
+
}
|
|
584
|
+
return map[str] || str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Export seluruh isi database SQLite ke objek JSON
|
|
590
|
+
*/
|
|
591
|
+
export function exportFullDatabase() {
|
|
592
|
+
const tables = {
|
|
593
|
+
config: dbStore.config.getAll(),
|
|
594
|
+
memories: dbStore.memories.getAll(),
|
|
595
|
+
sessions: dbStore.sessions.getAll(),
|
|
596
|
+
chatTurns: dbStore.chatTurns.getAll(),
|
|
597
|
+
chatArchives: dbStore.chatArchives.getAll(),
|
|
598
|
+
documents: dbStore.documents.getAll(),
|
|
599
|
+
relationships: dbStore.relationships.getAll(),
|
|
600
|
+
subagents: dbStore.subagents.getAll(),
|
|
601
|
+
subagentMessages: dbStore.subagentMessages.getAll(),
|
|
602
|
+
learnedSkills: dbStore.learnedSkills.getAll(),
|
|
603
|
+
agentTasks: dbStore.agentTasks.getAll(),
|
|
604
|
+
agentTaskSteps: dbStore.agentTaskSteps.getAll()
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return {
|
|
608
|
+
app: 'MARK',
|
|
609
|
+
version: '5.0.0',
|
|
610
|
+
exportedAt: new Date().toISOString(),
|
|
611
|
+
tables
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Import/Restore dump JSON (baik format V4 maupun format V5) ke database SQLite
|
|
617
|
+
*/
|
|
618
|
+
export function restoreFullDatabase(dumpData, { overwrite = true } = {}) {
|
|
619
|
+
if (!dumpData || typeof dumpData !== 'object') {
|
|
620
|
+
throw new Error('Format data backup tidak valid.')
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
const rawTables = dumpData.tables || dumpData
|
|
624
|
+
const results = {}
|
|
625
|
+
|
|
626
|
+
// Map nama tabel dari Dexie V4 ke skema SQLite V5
|
|
627
|
+
const tableMapping = {
|
|
628
|
+
config: dbStore.config,
|
|
629
|
+
memory: dbStore.memories,
|
|
630
|
+
memories: dbStore.memories,
|
|
631
|
+
sessions: dbStore.sessions,
|
|
632
|
+
chatTurns: dbStore.chatTurns,
|
|
633
|
+
chat_turns: dbStore.chatTurns,
|
|
634
|
+
chatArchive: dbStore.chatArchives,
|
|
635
|
+
chatArchives: dbStore.chatArchives,
|
|
636
|
+
chat_archives: dbStore.chatArchives,
|
|
637
|
+
documents: dbStore.documents,
|
|
638
|
+
relationships: dbStore.relationships,
|
|
639
|
+
subagents: dbStore.subagents,
|
|
640
|
+
subagent_messages: dbStore.subagentMessages,
|
|
641
|
+
subagentMessages: dbStore.subagentMessages,
|
|
642
|
+
learnedSkills: dbStore.learnedSkills,
|
|
643
|
+
learned_skills: dbStore.learnedSkills,
|
|
644
|
+
agentTasks: dbStore.agentTasks,
|
|
645
|
+
agent_tasks: dbStore.agentTasks,
|
|
646
|
+
agentTaskSteps: dbStore.agentTaskSteps,
|
|
647
|
+
agent_task_steps: dbStore.agentTaskSteps,
|
|
648
|
+
sessionCompact: dbStore.sessionCompact,
|
|
649
|
+
session_compact: dbStore.sessionCompact
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const restoreTransaction = sqlite.transaction(() => {
|
|
653
|
+
for (const [key, items] of Object.entries(rawTables)) {
|
|
654
|
+
const targetStore = tableMapping[key]
|
|
655
|
+
if (targetStore && Array.isArray(items)) {
|
|
656
|
+
if (overwrite) {
|
|
657
|
+
targetStore.clear()
|
|
658
|
+
}
|
|
659
|
+
for (const item of items) {
|
|
660
|
+
targetStore.insert(item)
|
|
661
|
+
}
|
|
662
|
+
results[key] = items.length
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// Jika dump memuat config, sinkronisasikan juga ke config.json server
|
|
667
|
+
const restoredConfig = rawTables.config
|
|
668
|
+
if (Array.isArray(restoredConfig) && restoredConfig.length > 0) {
|
|
669
|
+
try {
|
|
670
|
+
const confObj = restoredConfig[0]
|
|
671
|
+
const finalConf = confObj.data
|
|
672
|
+
? typeof confObj.data === 'string'
|
|
673
|
+
? JSON.parse(confObj.data)
|
|
674
|
+
: confObj.data
|
|
675
|
+
: confObj
|
|
676
|
+
const cfgPath = path.join(CONFIG_DIR, 'config.json')
|
|
677
|
+
fs.writeFileSync(cfgPath, JSON.stringify(finalConf, null, 2), 'utf-8')
|
|
678
|
+
} catch (err) {
|
|
679
|
+
void err
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
})
|
|
683
|
+
|
|
684
|
+
restoreTransaction()
|
|
685
|
+
return { success: true, imported: results }
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Reset seluruh data memori dan riwayat AI (semua tabel kecuali tabel 'config')
|
|
690
|
+
*/
|
|
691
|
+
export function resetAllExceptConfig() {
|
|
692
|
+
const resetTransaction = sqlite.transaction(() => {
|
|
693
|
+
// 1. Bersihkan tabel memori & percakapan
|
|
694
|
+
dbStore.memories.clear()
|
|
695
|
+
dbStore.sessions.clear()
|
|
696
|
+
dbStore.sessionCompact.clear()
|
|
697
|
+
dbStore.chatTurns.clear()
|
|
698
|
+
dbStore.chatArchives.clear()
|
|
699
|
+
dbStore.documents.clear()
|
|
700
|
+
dbStore.subagents.clear()
|
|
701
|
+
dbStore.subagentMessages.clear()
|
|
702
|
+
dbStore.learnedSkills.clear()
|
|
703
|
+
dbStore.agentTasks.clear()
|
|
704
|
+
dbStore.agentTaskSteps.clear()
|
|
705
|
+
|
|
706
|
+
// 2. Reset hubungan / sifat relasional ke nilai default awal
|
|
707
|
+
dbStore.relationships.clear()
|
|
708
|
+
dbStore.relationships.insert({
|
|
709
|
+
user_id: 'owner',
|
|
710
|
+
warmth: 0.5,
|
|
711
|
+
sarcasm_level: 0.5,
|
|
712
|
+
trust: 0.5,
|
|
713
|
+
energy: 0.5,
|
|
714
|
+
obedience: 0.8,
|
|
715
|
+
reasoning: 'Karakter dan memori AI direset ke pengaturan awal.',
|
|
716
|
+
new_relational_memory: '',
|
|
717
|
+
last_evaluation: null,
|
|
718
|
+
eval_count: 0,
|
|
719
|
+
last_chat_index: 0
|
|
720
|
+
})
|
|
721
|
+
|
|
722
|
+
// 3. Buat sesi awal default
|
|
723
|
+
dbStore.sessions.insert({
|
|
724
|
+
id: '1',
|
|
725
|
+
title: 'Main Thread',
|
|
726
|
+
data: JSON.stringify([]),
|
|
727
|
+
timestamp: Date.now(),
|
|
728
|
+
created_at: Date.now(),
|
|
729
|
+
updated_at: Date.now()
|
|
730
|
+
})
|
|
731
|
+
})
|
|
732
|
+
|
|
733
|
+
resetTransaction()
|
|
734
|
+
return {
|
|
735
|
+
success: true,
|
|
736
|
+
message: 'Seluruh data AI berhasil direset ke kondisi awal (konfigurasi dipertahankan).'
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
export const dbStore = {
|
|
741
|
+
sqlite,
|
|
742
|
+
config: new SqliteTable('config'),
|
|
743
|
+
memories: new SqliteTable('memories'),
|
|
744
|
+
sessions: new SqliteTable('sessions'),
|
|
745
|
+
sessionCompact: new SqliteTable('session_compact', 'session_id'),
|
|
746
|
+
chatTurns: new SqliteTable('chat_turns'),
|
|
747
|
+
chatArchives: new SqliteTable('chat_archives'),
|
|
748
|
+
documents: new SqliteTable('documents'),
|
|
749
|
+
relationships: new SqliteTable('relationships', 'user_id'),
|
|
750
|
+
subagents: new SqliteTable('subagents'),
|
|
751
|
+
subagentMessages: new SqliteTable('subagent_messages'),
|
|
752
|
+
learnedSkills: new SqliteTable('learned_skills'),
|
|
753
|
+
agentTasks: new SqliteTable('agent_tasks'),
|
|
754
|
+
agentTaskSteps: new SqliteTable('agent_task_steps'),
|
|
755
|
+
exportFullDatabase,
|
|
756
|
+
restoreFullDatabase,
|
|
757
|
+
resetAllExceptConfig
|
|
758
|
+
}
|