@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.
Files changed (227) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +209 -0
  3. package/bin/mark.js +27 -0
  4. package/out/renderer/assets/icon-DHo2CYph.svg +1 -0
  5. package/out/renderer/assets/index-G2fADWO-.js +4768 -0
  6. package/out/renderer/assets/index-f3mVse3c.css +1 -0
  7. package/out/renderer/assets/music-cover-CG4vi3kZ.png +0 -0
  8. package/out/renderer/assets/poppins-devanagari-400-normal-CJDn6rn8.woff2 +0 -0
  9. package/out/renderer/assets/poppins-devanagari-400-normal-CqVvlrh5.woff +0 -0
  10. package/out/renderer/assets/poppins-devanagari-500-normal-BIdkeU1p.woff2 +0 -0
  11. package/out/renderer/assets/poppins-devanagari-500-normal-DMPDjHtT.woff +0 -0
  12. package/out/renderer/assets/poppins-devanagari-600-normal-ClASKHrr.woff +0 -0
  13. package/out/renderer/assets/poppins-devanagari-600-normal-STEjXBNN.woff2 +0 -0
  14. package/out/renderer/assets/poppins-devanagari-700-normal-O-jipLrW.woff2 +0 -0
  15. package/out/renderer/assets/poppins-devanagari-700-normal-fHs-vx92.woff +0 -0
  16. package/out/renderer/assets/poppins-latin-400-normal-BOb3E3N0.woff +0 -0
  17. package/out/renderer/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
  18. package/out/renderer/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
  19. package/out/renderer/assets/poppins-latin-500-normal-DGXqpDMm.woff +0 -0
  20. package/out/renderer/assets/poppins-latin-600-normal-BJdTmd5m.woff +0 -0
  21. package/out/renderer/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
  22. package/out/renderer/assets/poppins-latin-700-normal-BVuQR_eA.woff +0 -0
  23. package/out/renderer/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
  24. package/out/renderer/assets/poppins-latin-ext-400-normal-DaBSavcJ.woff +0 -0
  25. package/out/renderer/assets/poppins-latin-ext-400-normal-by3JarPu.woff2 +0 -0
  26. package/out/renderer/assets/poppins-latin-ext-500-normal-CK-6C4Hw.woff2 +0 -0
  27. package/out/renderer/assets/poppins-latin-ext-500-normal-CgAe2rWW.woff +0 -0
  28. package/out/renderer/assets/poppins-latin-ext-600-normal-CAhIAdZj.woff2 +0 -0
  29. package/out/renderer/assets/poppins-latin-ext-600-normal-Df5ffKXP.woff +0 -0
  30. package/out/renderer/assets/poppins-latin-ext-700-normal-DctTR6Tg.woff +0 -0
  31. package/out/renderer/assets/poppins-latin-ext-700-normal-cby-RkWa.woff2 +0 -0
  32. package/out/renderer/favicon.ico +0 -0
  33. package/out/renderer/icon-256.png +0 -0
  34. package/out/renderer/icon.svg +1 -0
  35. package/out/renderer/index.html +25 -0
  36. package/out/renderer/manifest.json +25 -0
  37. package/out/renderer/robot-simulator.html +1640 -0
  38. package/package.json +106 -0
  39. package/src/cli/index.js +332 -0
  40. package/src/cli/monitor.js +413 -0
  41. package/src/cli/theme.js +347 -0
  42. package/src/launcher/MarkTray.cs +227 -0
  43. package/src/main/browser-agent.js +1132 -0
  44. package/src/main/git-service.js +90 -0
  45. package/src/main/google/google-calendar.js +69 -0
  46. package/src/main/google/google-drive.js +263 -0
  47. package/src/main/google/google-gmail.js +131 -0
  48. package/src/main/google/google-service.js +241 -0
  49. package/src/main/node-tools.js +23 -0
  50. package/src/main/pc-agent-scripts/mouse-locker.ps1 +76 -0
  51. package/src/main/pc-agent-scripts/ocr-region.ps1 +185 -0
  52. package/src/main/pc-agent-scripts/pc-daemon.ps1 +726 -0
  53. package/src/main/pc-agent-scripts/pc-overlay.ps1 +253 -0
  54. package/src/main/pc-agent-scripts/pick-folder.ps1 +33 -0
  55. package/src/main/pc-agent-scripts/read-ui.ps1 +181 -0
  56. package/src/main/pc-agent-scripts/take-screenshot.ps1 +24 -0
  57. package/src/main/pc-agent-scripts/win-action.ps1 +380 -0
  58. package/src/main/plugins/plugin-loader.js +306 -0
  59. package/src/main/skills/skill-manager.js +265 -0
  60. package/src/main/syntax-validator.js +455 -0
  61. package/src/main/task-daemon.js +117 -0
  62. package/src/main/telegram/telegram-service.js +835 -0
  63. package/src/main/tools/browser-tools.js +516 -0
  64. package/src/main/tools/file-tools.js +1126 -0
  65. package/src/main/tools/git-tools.js +79 -0
  66. package/src/main/tools/google-tools.js +566 -0
  67. package/src/main/tools/index.js +36 -0
  68. package/src/main/tools/media-tools.js +42 -0
  69. package/src/main/tools/system-tools.js +295 -0
  70. package/src/main/tools/task-tools.js +73 -0
  71. package/src/main/tools/telegram-tools.js +101 -0
  72. package/src/renderer/index.html +24 -0
  73. package/src/renderer/public/favicon.ico +0 -0
  74. package/src/renderer/public/icon-256.png +0 -0
  75. package/src/renderer/public/icon.svg +1 -0
  76. package/src/renderer/public/manifest.json +25 -0
  77. package/src/renderer/public/robot-simulator.html +1640 -0
  78. package/src/renderer/src/App.jsx +304 -0
  79. package/src/renderer/src/api/ai/awareness.js +294 -0
  80. package/src/renderer/src/api/ai/chatSummarizer.js +79 -0
  81. package/src/renderer/src/api/ai/contextCompactor.js +129 -0
  82. package/src/renderer/src/api/ai/contextManager.js +1130 -0
  83. package/src/renderer/src/api/ai/core.js +167 -0
  84. package/src/renderer/src/api/ai/index.js +4 -0
  85. package/src/renderer/src/api/ai/memoryGroomer.js +101 -0
  86. package/src/renderer/src/api/ai/persona.js +115 -0
  87. package/src/renderer/src/api/ai/planning.js +317 -0
  88. package/src/renderer/src/api/ai/relationship.js +177 -0
  89. package/src/renderer/src/api/ai/skillSynthesizer.js +168 -0
  90. package/src/renderer/src/api/ai/tools.js +167 -0
  91. package/src/renderer/src/api/ai/utils.js +359 -0
  92. package/src/renderer/src/api/db.js +1013 -0
  93. package/src/renderer/src/api/oramaStore.js +592 -0
  94. package/src/renderer/src/api/ragPipeline.js +87 -0
  95. package/src/renderer/src/api/subagent/subagentExecutor.js +780 -0
  96. package/src/renderer/src/api/subagent/subagentPrompt.js +44 -0
  97. package/src/renderer/src/api/subagent/subagentStore.js +173 -0
  98. package/src/renderer/src/api/taskExecutor.js +18 -0
  99. package/src/renderer/src/api/taskStore.js +315 -0
  100. package/src/renderer/src/api/tools/core-tools.js +707 -0
  101. package/src/renderer/src/api/tools/index.js +151 -0
  102. package/src/renderer/src/api/turnPairMigrator.js +200 -0
  103. package/src/renderer/src/api/vectorMemory.js +136 -0
  104. package/src/renderer/src/api/wakeWord.js +101 -0
  105. package/src/renderer/src/api/web-bridge.js +885 -0
  106. package/src/renderer/src/api/webSpeech.js +178 -0
  107. package/src/renderer/src/api/workspaceRag.js +76 -0
  108. package/src/renderer/src/assets/electron.svg +10 -0
  109. package/src/renderer/src/assets/icon.svg +1 -0
  110. package/src/renderer/src/assets/main.css +589 -0
  111. package/src/renderer/src/assets/music-cover.png +0 -0
  112. package/src/renderer/src/assets/wavy-lines.svg +25 -0
  113. package/src/renderer/src/components/Chat/ApprovalBubble.jsx +127 -0
  114. package/src/renderer/src/components/Chat/CodeBlock.jsx +83 -0
  115. package/src/renderer/src/components/Chat/DurableTaskBubble.jsx +455 -0
  116. package/src/renderer/src/components/Chat/FileDiffModal.jsx +328 -0
  117. package/src/renderer/src/components/Chat/GeminiWidgets.jsx +82 -0
  118. package/src/renderer/src/components/Chat/MemoryFooterBubble.jsx +34 -0
  119. package/src/renderer/src/components/Chat/MessageBubble.jsx +459 -0
  120. package/src/renderer/src/components/Chat/PluginExecutionBubble.jsx +41 -0
  121. package/src/renderer/src/components/Chat/ThinkingBubble.jsx +316 -0
  122. package/src/renderer/src/components/Chat/YoutubeSearchBubble.jsx +43 -0
  123. package/src/renderer/src/components/Chat/YoutubeSummaryBubble.jsx +40 -0
  124. package/src/renderer/src/components/Chat/index.js +11 -0
  125. package/src/renderer/src/components/ChatList.jsx +434 -0
  126. package/src/renderer/src/components/GlobalCameraManager.jsx +67 -0
  127. package/src/renderer/src/components/Versions.jsx +15 -0
  128. package/src/renderer/src/components/YoutubeMusicPlayer.jsx +375 -0
  129. package/src/renderer/src/components/camera/CameraPreview.jsx +236 -0
  130. package/src/renderer/src/components/config/AiEngineSection.jsx +363 -0
  131. package/src/renderer/src/components/config/CameraSection.jsx +100 -0
  132. package/src/renderer/src/components/config/PermissionsSection.jsx +130 -0
  133. package/src/renderer/src/components/config/ShortcutSection.jsx +102 -0
  134. package/src/renderer/src/components/config/VoiceSection.jsx +110 -0
  135. package/src/renderer/src/components/config/index.js +5 -0
  136. package/src/renderer/src/components/core/Avatar.jsx +2197 -0
  137. package/src/renderer/src/components/core/ConfirmModal.jsx +80 -0
  138. package/src/renderer/src/components/core/DraggableHoloCard.jsx +125 -0
  139. package/src/renderer/src/components/core/FloatingMenu.jsx +272 -0
  140. package/src/renderer/src/components/core/HoloCard.jsx +64 -0
  141. package/src/renderer/src/components/core/InputBar.jsx +1346 -0
  142. package/src/renderer/src/components/core/ProcessPanel.jsx +216 -0
  143. package/src/renderer/src/components/core/ResponseArea.jsx +149 -0
  144. package/src/renderer/src/components/core/StatusIndicator.jsx +59 -0
  145. package/src/renderer/src/components/core/ThoughtNeuralFlow.jsx +168 -0
  146. package/src/renderer/src/components/core/ToolClustersDeck.jsx +210 -0
  147. package/src/renderer/src/components/core/native-skills.js +43 -0
  148. package/src/renderer/src/components/neural-core/EmotionalCortexLobe.jsx +359 -0
  149. package/src/renderer/src/components/neural-core/NodeDissectionModal.jsx +57 -0
  150. package/src/renderer/src/components/neural-core/ProceduralMatrixLobe.jsx +193 -0
  151. package/src/renderer/src/components/neural-core/ProceduralSkillModal.jsx +53 -0
  152. package/src/renderer/src/components/neural-core/ResetAiModal.jsx +198 -0
  153. package/src/renderer/src/components/neural-core/SynapticMemoryLobe.jsx +204 -0
  154. package/src/renderer/src/components/neural-core/traitMeta.js +102 -0
  155. package/src/renderer/src/components/subagent/AgentChatFeed.jsx +603 -0
  156. package/src/renderer/src/components/subagent/AgentInspector.jsx +224 -0
  157. package/src/renderer/src/components/subagent/AgentSidebar.jsx +216 -0
  158. package/src/renderer/src/components/subagent/SubagentIntercom.jsx +572 -0
  159. package/src/renderer/src/components/subagent/SubagentTopologyMap.jsx +423 -0
  160. package/src/renderer/src/contexts/ApprovalContext.jsx +425 -0
  161. package/src/renderer/src/contexts/ChatContext.jsx +61 -0
  162. package/src/renderer/src/contexts/YoutubeMusicContext.jsx +333 -0
  163. package/src/renderer/src/data/faqData.js +202 -0
  164. package/src/renderer/src/hooks/agent/executeAgentTool.js +895 -0
  165. package/src/renderer/src/hooks/agent/index.js +4 -0
  166. package/src/renderer/src/hooks/agent/useMarkMusic.js +75 -0
  167. package/src/renderer/src/hooks/agent/useMarkPlan.js +2739 -0
  168. package/src/renderer/src/hooks/agent/useMarkState.js +173 -0
  169. package/src/renderer/src/hooks/agent/useMarkYoutube.js +82 -0
  170. package/src/renderer/src/hooks/agent/useRelationalGrowth.js +201 -0
  171. package/src/renderer/src/hooks/telegram/useTelegramBot.js +63 -0
  172. package/src/renderer/src/hooks/useAwareness.js +289 -0
  173. package/src/renderer/src/hooks/useChatArchiver.js +52 -0
  174. package/src/renderer/src/hooks/useConfirm.jsx +68 -0
  175. package/src/renderer/src/hooks/useMarkAgent.js +454 -0
  176. package/src/renderer/src/hooks/useMemoryGroomer.js +152 -0
  177. package/src/renderer/src/hooks/useVAD.js +511 -0
  178. package/src/renderer/src/hooks/useWebSpeechWakeWord.js +122 -0
  179. package/src/renderer/src/main.jsx +12 -0
  180. package/src/renderer/src/pages/ChatStudio.jsx +922 -0
  181. package/src/renderer/src/pages/Configuration.jsx +360 -0
  182. package/src/renderer/src/pages/GoogleWorkspace.jsx +293 -0
  183. package/src/renderer/src/pages/Guidebook.jsx +917 -0
  184. package/src/renderer/src/pages/Knowledge.jsx +241 -0
  185. package/src/renderer/src/pages/MarkHome.jsx +491 -0
  186. package/src/renderer/src/pages/NeuralCore.jsx +786 -0
  187. package/src/renderer/src/pages/Plugins.jsx +630 -0
  188. package/src/renderer/src/pages/SkillEditor.jsx +380 -0
  189. package/src/renderer/src/pages/Skills.jsx +219 -0
  190. package/src/renderer/src/pages/Subagents.jsx +342 -0
  191. package/src/renderer/src/pages/TelegramBot.jsx +343 -0
  192. package/src/renderer/src/utils/chatContentParser.js +203 -0
  193. package/src/renderer/src/utils/toolClusters.js +201 -0
  194. package/src/server/bin/sha3_wasm_bg.wasm +0 -0
  195. package/src/server/config-manager.js +57 -0
  196. package/src/server/index.js +195 -0
  197. package/src/server/launcher.js +87 -0
  198. package/src/server/memory/db-store.js +758 -0
  199. package/src/server/memory/orama-store.js +177 -0
  200. package/src/server/memory/vector-engine.js +109 -0
  201. package/src/server/routes/ai.routes.js +280 -0
  202. package/src/server/routes/awareness.routes.js +62 -0
  203. package/src/server/routes/chat.routes.js +61 -0
  204. package/src/server/routes/config.routes.js +41 -0
  205. package/src/server/routes/index.js +35 -0
  206. package/src/server/routes/integrations.routes.js +116 -0
  207. package/src/server/routes/memory.routes.js +256 -0
  208. package/src/server/routes/plugins.routes.js +72 -0
  209. package/src/server/routes/skills.routes.js +139 -0
  210. package/src/server/routes/subagents.routes.js +70 -0
  211. package/src/server/routes/tasks.routes.js +175 -0
  212. package/src/server/routes/workspace.routes.js +127 -0
  213. package/src/server/services/ai/ai-utils.js +161 -0
  214. package/src/server/services/ai/openai-provider.js +757 -0
  215. package/src/server/services/ai/web-provider.js +729 -0
  216. package/src/server/services/ai-bridge.js +46 -0
  217. package/src/server/services/deepseek-web.js +956 -0
  218. package/src/server/services/gemini-web.js +170 -0
  219. package/src/server/services/notification-service.js +91 -0
  220. package/src/server/services/updater.js +125 -0
  221. package/src/server/tools/awareness-tracker.js +292 -0
  222. package/src/server/tools/group-tools.js +1164 -0
  223. package/src/server/tools/media-tools.js +244 -0
  224. package/src/server/tools/pc-agent.js +327 -0
  225. package/src/server/tools/screen-service.js +51 -0
  226. package/src/server/ws-hub.js +168 -0
  227. package/src/shared/parsers/mark-tag-parser.js +275 -0
@@ -0,0 +1,1164 @@
1
+ /**
2
+ * Group Tools Definition & OpenAPI Function Schema untuk MARK V5.
3
+ * Seluruh nama tool mempertahankan format kebab-case (100% valid sesuai regex OpenAPI ^[a-zA-Z0-9_-]{1,64}$).
4
+ */
5
+
6
+ export const GROUP_TOOLS_SCHEMA = {
7
+ advanced_browser: {
8
+ description: 'Tool untuk navigasi dan kontrol elemen fisik browser web secara detail.',
9
+ tools: [
10
+ {
11
+ type: 'function',
12
+ function: {
13
+ name: 'browser-search',
14
+ description:
15
+ 'HANYA untuk mencari dan menemukan URL / link website yang relevan dengan kata kunci (bukan untuk membaca isi artikel lengkap). Mengembalikan daftar judul & URL. Untuk membaca isi konten lengkap dari URL yang ditemukan, gunakan tool lainnya seperti "browser-fetch".',
16
+ parameters: {
17
+ type: 'object',
18
+ properties: {
19
+ query: { type: 'string', description: 'Kata kunci pencarian web' }
20
+ },
21
+ required: ['query'],
22
+ additionalProperties: false
23
+ }
24
+ }
25
+ },
26
+ {
27
+ type: 'function',
28
+ function: {
29
+ name: 'browser-fetch',
30
+ description:
31
+ 'Membaca dan mengambil (curl/fetch) isi konten teks/artikel dari suatu URL secara instan tanpa perlu membuka jendela browser fisik.',
32
+ parameters: {
33
+ type: 'object',
34
+ properties: {
35
+ url: { type: 'string', description: 'URL lengkap website tujuan' },
36
+ max_chars: { type: 'number', description: 'Batas karakter teks (default 4000)' }
37
+ },
38
+ required: ['url'],
39
+ additionalProperties: false
40
+ }
41
+ }
42
+ },
43
+ {
44
+ type: 'function',
45
+ function: {
46
+ name: 'browser-navigate',
47
+ description:
48
+ 'Buka URL di browser fisik. Mengembalikan daftar elemen interaktif bernomor (ID).',
49
+ parameters: {
50
+ type: 'object',
51
+ properties: {
52
+ url: { type: 'string', description: 'URL lengkap website tujuan' }
53
+ },
54
+ required: ['url'],
55
+ additionalProperties: false
56
+ }
57
+ }
58
+ },
59
+ {
60
+ type: 'function',
61
+ function: {
62
+ name: 'browser-read',
63
+ description: 'Scan ulang elemen halaman browser saat ini.',
64
+ parameters: {
65
+ type: 'object',
66
+ properties: {},
67
+ additionalProperties: false
68
+ }
69
+ }
70
+ },
71
+ {
72
+ type: 'function',
73
+ function: {
74
+ name: 'browser-click',
75
+ description: 'Klik elemen pada halaman browser berdasarkan ID numerik.',
76
+ parameters: {
77
+ type: 'object',
78
+ properties: {
79
+ element_id: { type: 'number', description: 'ID numerik elemen interaktif' }
80
+ },
81
+ required: ['element_id'],
82
+ additionalProperties: false
83
+ }
84
+ }
85
+ },
86
+ {
87
+ type: 'function',
88
+ function: {
89
+ name: 'browser-type',
90
+ description: 'Ketik teks ke kolom input formulir web berdasarkan ID elemen.',
91
+ parameters: {
92
+ type: 'object',
93
+ properties: {
94
+ element_id: { type: 'number', description: 'ID elemen input' },
95
+ text: { type: 'string', description: 'Teks yang akan diketikkan' }
96
+ },
97
+ required: ['element_id', 'text'],
98
+ additionalProperties: false
99
+ }
100
+ }
101
+ },
102
+ {
103
+ type: 'function',
104
+ function: {
105
+ name: 'browser-scroll',
106
+ description: 'Scroll halaman browser ke atas atau ke bawah.',
107
+ parameters: {
108
+ type: 'object',
109
+ properties: {
110
+ direction: { type: 'string', enum: ['up', 'down'], description: 'Arah scroll' }
111
+ },
112
+ required: ['direction'],
113
+ additionalProperties: false
114
+ }
115
+ }
116
+ },
117
+ {
118
+ type: 'function',
119
+ function: {
120
+ name: 'browser-extract',
121
+ description: 'Ekstrak teks atau data dari web via CSS Selector.',
122
+ parameters: {
123
+ type: 'object',
124
+ properties: {
125
+ selector: { type: 'string', description: 'CSS Selector target' }
126
+ },
127
+ required: ['selector'],
128
+ additionalProperties: false
129
+ }
130
+ }
131
+ },
132
+ {
133
+ type: 'function',
134
+ function: {
135
+ name: 'browser-script',
136
+ description: 'Eksekusi JavaScript langsung pada halaman browser web.',
137
+ parameters: {
138
+ type: 'object',
139
+ properties: {
140
+ script: { type: 'string', description: 'Kode JavaScript yang akan dieksekusi' }
141
+ },
142
+ required: ['script'],
143
+ additionalProperties: false
144
+ }
145
+ }
146
+ },
147
+ {
148
+ type: 'function',
149
+ function: {
150
+ name: 'browser-screenshot',
151
+ description:
152
+ 'Mengambil tangkapan layar (screenshot) halaman browser web Puppeteer. Jika parameter query disertakan, tampilan visual halaman web akan langsung dianalisis oleh AI Vision.',
153
+ parameters: {
154
+ type: 'object',
155
+ properties: {
156
+ filename: {
157
+ type: 'string',
158
+ description: 'Nama berkas tujuan screenshot (.png, opsional)'
159
+ },
160
+ query: {
161
+ type: 'string',
162
+ description:
163
+ 'Instruksi atau pertanyaan analisis visual terhadap tampilan halaman web (opsional)'
164
+ }
165
+ },
166
+ additionalProperties: false
167
+ }
168
+ }
169
+ },
170
+ {
171
+ type: 'function',
172
+ function: {
173
+ name: 'browser-download',
174
+ description: 'Mengunduh berkas dari web ke komputer.',
175
+ parameters: {
176
+ type: 'object',
177
+ properties: {
178
+ url: { type: 'string', description: 'URL berkas yang akan diunduh' },
179
+ filename: { type: 'string', description: 'Nama berkas yang disimpan' }
180
+ },
181
+ required: ['url', 'filename'],
182
+ additionalProperties: false
183
+ }
184
+ }
185
+ },
186
+ {
187
+ type: 'function',
188
+ function: {
189
+ name: 'browser-ask-user',
190
+ description:
191
+ 'Minta bantuan user untuk menyelesaikan CAPTCHA, 2FA, verifikasi Cloudflare, atau login manual pada halaman browser. Jendela browser akan otomatis ditampilkan dan interaksi user di-unblock sementara hingga user menekan tombol Resume.',
192
+ parameters: {
193
+ type: 'object',
194
+ properties: {
195
+ prompt: {
196
+ type: 'string',
197
+ description:
198
+ 'Pesan arahan untuk user (misal: "Silakan selesaikan Cloudflare Turnstile / Login Google terlebih dahulu")'
199
+ }
200
+ },
201
+ required: ['prompt'],
202
+ additionalProperties: false
203
+ }
204
+ }
205
+ },
206
+ {
207
+ type: 'function',
208
+ function: {
209
+ name: 'browser-close',
210
+ description: 'Menutup sesi browser fisik yang sedang aktif.',
211
+ parameters: {
212
+ type: 'object',
213
+ properties: {},
214
+ additionalProperties: false
215
+ }
216
+ }
217
+ }
218
+ ]
219
+ },
220
+ pc_automation: {
221
+ description:
222
+ 'Tool untuk interaksi fisik dengan desktop OS Windows, mouse click, keyboard typing, dan window management.',
223
+ tools: [
224
+ {
225
+ type: 'function',
226
+ function: {
227
+ name: 'os-control-open',
228
+ description:
229
+ 'WAJIB DIPANGGIL PERTAMA KALI sebelum memulai rangkaian tugas otomatisasi PC. Mengunci sesi dan memunculkan overlay pengunci PC.',
230
+ parameters: {
231
+ type: 'object',
232
+ properties: {},
233
+ additionalProperties: false
234
+ }
235
+ }
236
+ },
237
+ {
238
+ type: 'function',
239
+ function: {
240
+ name: 'os-control-close',
241
+ description: 'WAJIB DIPANGGIL TERAKHIR setelah semua tugas otomatisasi PC selesai.',
242
+ parameters: {
243
+ type: 'object',
244
+ properties: {},
245
+ additionalProperties: false
246
+ }
247
+ }
248
+ },
249
+ {
250
+ type: 'function',
251
+ function: {
252
+ name: 'os-read',
253
+ description: 'Membaca elemen GUI desktop.',
254
+ parameters: {
255
+ type: 'object',
256
+ properties: {
257
+ mode: {
258
+ type: 'string',
259
+ enum: ['all', 'focus'],
260
+ description:
261
+ '"all" untuk scan seluruh layar atau "focus" untuk membaca 1 elemen aktif'
262
+ }
263
+ },
264
+ additionalProperties: false
265
+ }
266
+ }
267
+ },
268
+ {
269
+ type: 'function',
270
+ function: {
271
+ name: 'os-click',
272
+ description:
273
+ 'Klik mouse pada elemen GUI desktop berdasarkan ID elemen atau koordinat x||y.',
274
+ parameters: {
275
+ type: 'object',
276
+ properties: {
277
+ target: {
278
+ type: 'string',
279
+ description: 'ID elemen dari os-read atau koordinat "x||y"'
280
+ }
281
+ },
282
+ required: ['target'],
283
+ additionalProperties: false
284
+ }
285
+ }
286
+ },
287
+ {
288
+ type: 'function',
289
+ function: {
290
+ name: 'os-double-click',
291
+ description:
292
+ 'Double click mouse pada elemen GUI desktop berdasarkan ID elemen atau koordinat x||y.',
293
+ parameters: {
294
+ type: 'object',
295
+ properties: {
296
+ target: {
297
+ type: 'string',
298
+ description: 'ID elemen dari os-read atau koordinat "x||y"'
299
+ }
300
+ },
301
+ required: ['target'],
302
+ additionalProperties: false
303
+ }
304
+ }
305
+ },
306
+ {
307
+ type: 'function',
308
+ function: {
309
+ name: 'os-type',
310
+ description: 'Ketik teks ke aplikasi Windows yang sedang aktif.',
311
+ parameters: {
312
+ type: 'object',
313
+ properties: {
314
+ text: { type: 'string', description: 'Teks yang akan diketikkan' }
315
+ },
316
+ required: ['text'],
317
+ additionalProperties: false
318
+ }
319
+ }
320
+ },
321
+ {
322
+ type: 'function',
323
+ function: {
324
+ name: 'os-key',
325
+ description: 'Tekan kombinasi tombol keyboard shortcut (misal: ctrl+c, alt+tab, enter).',
326
+ parameters: {
327
+ type: 'object',
328
+ properties: {
329
+ combo: { type: 'string', description: 'Kombinasi tombol keyboard' }
330
+ },
331
+ required: ['combo'],
332
+ additionalProperties: false
333
+ }
334
+ }
335
+ },
336
+ {
337
+ type: 'function',
338
+ function: {
339
+ name: 'os-scroll',
340
+ description: 'Scroll mouse wheel di aplikasi aktif.',
341
+ parameters: {
342
+ type: 'object',
343
+ properties: {
344
+ direction: { type: 'string', enum: ['up', 'down'], description: 'Arah scroll' },
345
+ amount: { type: 'number', description: 'Jumlah baris scroll' }
346
+ },
347
+ required: ['direction'],
348
+ additionalProperties: false
349
+ }
350
+ }
351
+ },
352
+ {
353
+ type: 'function',
354
+ function: {
355
+ name: 'os-delay',
356
+ description: 'Menunggu beberapa milidetik (jeda) saat menjalankan otomatisasi UI.',
357
+ parameters: {
358
+ type: 'object',
359
+ properties: {
360
+ ms: { type: 'number', description: 'Durasi jeda dalam milidetik (contoh: 1000)' }
361
+ },
362
+ required: ['ms'],
363
+ additionalProperties: false
364
+ }
365
+ }
366
+ },
367
+ {
368
+ type: 'function',
369
+ function: {
370
+ name: 'os-search',
371
+ description: 'Mencari aplikasi di Start Menu Windows dengan tombol Windows.',
372
+ parameters: {
373
+ type: 'object',
374
+ properties: {
375
+ keyword: { type: 'string', description: 'Kata kunci nama aplikasi' }
376
+ },
377
+ required: ['keyword'],
378
+ additionalProperties: false
379
+ }
380
+ }
381
+ },
382
+ {
383
+ type: 'function',
384
+ function: {
385
+ name: 'os-list-windows',
386
+ description: 'Menampilkan daftar semua window aplikasi yang terbuka beserta judulnya.',
387
+ parameters: {
388
+ type: 'object',
389
+ properties: {},
390
+ additionalProperties: false
391
+ }
392
+ }
393
+ },
394
+ {
395
+ type: 'function',
396
+ function: {
397
+ name: 'os-focus-window',
398
+ description:
399
+ 'Fokus sebuah window aplikasi berdasarkan judul yang ada di os-list-windows.',
400
+ parameters: {
401
+ type: 'object',
402
+ properties: {
403
+ title: { type: 'string', description: 'Judul window aplikasi persis' }
404
+ },
405
+ required: ['title'],
406
+ additionalProperties: false
407
+ }
408
+ }
409
+ }
410
+ ]
411
+ },
412
+ youtube_music: {
413
+ description: 'Integrasi pencarian YouTube dan pemutar musik lokal.',
414
+ tools: [
415
+ {
416
+ type: 'function',
417
+ function: {
418
+ name: 'yt-search',
419
+ description: 'Mencari video di YouTube.',
420
+ parameters: {
421
+ type: 'object',
422
+ properties: {
423
+ query: { type: 'string', description: 'Kata kunci pencarian YouTube' }
424
+ },
425
+ required: ['query'],
426
+ additionalProperties: false
427
+ }
428
+ }
429
+ },
430
+ {
431
+ type: 'function',
432
+ function: {
433
+ name: 'yt-summary',
434
+ description: 'Merangkum isi video YouTube.',
435
+ parameters: {
436
+ type: 'object',
437
+ properties: {
438
+ url: { type: 'string', description: 'URL video YouTube' }
439
+ },
440
+ required: ['url'],
441
+ additionalProperties: false
442
+ }
443
+ }
444
+ },
445
+ {
446
+ type: 'function',
447
+ function: {
448
+ name: 'music-play',
449
+ description:
450
+ 'Memutar lagu di YouTube Music. Masukkan judul atau genre/mood lagu pada parameter title.',
451
+ parameters: {
452
+ type: 'object',
453
+ properties: {
454
+ title: {
455
+ type: 'string',
456
+ description:
457
+ 'Judul lagu, nama artis, atau kata kunci pencarian lagu yang ingin diputar (contoh: "Bohemian Rhapsody", "Lagu Pop Santai")'
458
+ }
459
+ },
460
+ required: ['title'],
461
+ additionalProperties: false
462
+ }
463
+ }
464
+ },
465
+ {
466
+ type: 'function',
467
+ function: {
468
+ name: 'music-toggle',
469
+ description: 'Pause atau lanjut memutar musik.',
470
+ parameters: {
471
+ type: 'object',
472
+ properties: {},
473
+ additionalProperties: false
474
+ }
475
+ }
476
+ },
477
+ {
478
+ type: 'function',
479
+ function: {
480
+ name: 'music-next',
481
+ description: 'Memutar lagu berikutnya di daftar antrean pemutar musik.',
482
+ parameters: {
483
+ type: 'object',
484
+ properties: {},
485
+ additionalProperties: false
486
+ }
487
+ }
488
+ },
489
+ {
490
+ type: 'function',
491
+ function: {
492
+ name: 'music-prev',
493
+ description: 'Memutar lagu sebelumnya di daftar antrean pemutar musik.',
494
+ parameters: {
495
+ type: 'object',
496
+ properties: {},
497
+ additionalProperties: false
498
+ }
499
+ }
500
+ }
501
+ ]
502
+ },
503
+ google_drive: {
504
+ description:
505
+ 'Manajemen penyimpanan dan berkas Google Drive (Docs, Sheets, TXT, Upload, Search).',
506
+ tools: [
507
+ {
508
+ type: 'function',
509
+ function: {
510
+ name: 'gdrive-info',
511
+ description: 'Mengecek kapasitas sisa penyimpanan dan informasi akun Google Drive.',
512
+ parameters: {
513
+ type: 'object',
514
+ properties: {},
515
+ additionalProperties: false
516
+ }
517
+ }
518
+ },
519
+ {
520
+ type: 'function',
521
+ function: {
522
+ name: 'gdrive-search',
523
+ description: 'Mencari berkas di Google Drive berdasarkan nama atau konten.',
524
+ parameters: {
525
+ type: 'object',
526
+ properties: {
527
+ query: { type: 'string', description: 'Kata kunci pencarian berkas' },
528
+ pagination: {
529
+ type: 'string',
530
+ description: 'Rentang hasil pagination (contoh: "0-10")'
531
+ }
532
+ },
533
+ required: ['query'],
534
+ additionalProperties: false
535
+ }
536
+ }
537
+ },
538
+ {
539
+ type: 'function',
540
+ function: {
541
+ name: 'gdrive-list',
542
+ description: 'Melihat daftar berkas di Google Drive (atau folder tertentu).',
543
+ parameters: {
544
+ type: 'object',
545
+ properties: {
546
+ folder_id: {
547
+ type: 'string',
548
+ description: 'ID folder target (opsional, kosongkan untuk root)'
549
+ },
550
+ pagination: {
551
+ type: 'string',
552
+ description: 'Rentang hasil pagination (contoh: "0-10")'
553
+ }
554
+ },
555
+ additionalProperties: false
556
+ }
557
+ }
558
+ },
559
+ {
560
+ type: 'function',
561
+ function: {
562
+ name: 'gdrive-read',
563
+ description:
564
+ 'Membaca dan mengekstrak teks dari Google Docs, Sheets, atau TXT berdasarkan file ID.',
565
+ parameters: {
566
+ type: 'object',
567
+ properties: {
568
+ file_id: { type: 'string', description: 'ID berkas Google Drive yang akan dibaca' }
569
+ },
570
+ required: ['file_id'],
571
+ additionalProperties: false
572
+ }
573
+ }
574
+ },
575
+ {
576
+ type: 'function',
577
+ function: {
578
+ name: 'gdrive-upload',
579
+ description:
580
+ 'Mengunggah berkas lokal (PDF, dokumen, gambar, zip, dll.) dari komputer ke Google Drive.',
581
+ parameters: {
582
+ type: 'object',
583
+ properties: {
584
+ file_path: {
585
+ type: 'string',
586
+ description:
587
+ 'Path absolut atau relatif berkas lokal yang akan diunggah (misal: "C:\\Users\\...\\laporan.pdf")'
588
+ }
589
+ },
590
+ required: ['file_path'],
591
+ additionalProperties: false
592
+ }
593
+ }
594
+ },
595
+ {
596
+ type: 'function',
597
+ function: {
598
+ name: 'gdrive-create',
599
+ description: 'Membuat dokumen kosong baru atau folder di Google Drive.',
600
+ parameters: {
601
+ type: 'object',
602
+ properties: {
603
+ name: { type: 'string', description: 'Nama dokumen atau folder baru' },
604
+ type: {
605
+ type: 'string',
606
+ enum: ['doc', 'sheet', 'folder'],
607
+ description: 'Tipe yang dibuat'
608
+ }
609
+ },
610
+ required: ['name'],
611
+ additionalProperties: false
612
+ }
613
+ }
614
+ },
615
+ {
616
+ type: 'function',
617
+ function: {
618
+ name: 'gdrive-move',
619
+ description: 'Memindahkan berkas ke folder lain di Google Drive.',
620
+ parameters: {
621
+ type: 'object',
622
+ properties: {
623
+ file_id: { type: 'string', description: 'ID berkas yang akan dipindah' },
624
+ folder_id: { type: 'string', description: 'ID folder tujuan' }
625
+ },
626
+ required: ['file_id', 'folder_id'],
627
+ additionalProperties: false
628
+ }
629
+ }
630
+ },
631
+ {
632
+ type: 'function',
633
+ function: {
634
+ name: 'gdrive-copy',
635
+ description: 'Menduplikasi berkas di Google Drive.',
636
+ parameters: {
637
+ type: 'object',
638
+ properties: {
639
+ file_id: { type: 'string', description: 'ID berkas yang akan disalin' },
640
+ new_name: { type: 'string', description: 'Nama baru berkas duplikat' }
641
+ },
642
+ required: ['file_id', 'new_name'],
643
+ additionalProperties: false
644
+ }
645
+ }
646
+ },
647
+ {
648
+ type: 'function',
649
+ function: {
650
+ name: 'gdrive-share',
651
+ description:
652
+ 'Mengubah izin akses atau membagikan berkas di Google Drive (misal: publik siapa saja dengan tautan, atau email tertentu).',
653
+ parameters: {
654
+ type: 'object',
655
+ properties: {
656
+ file_id: {
657
+ type: 'string',
658
+ description: 'ID berkas Google Drive yang ingin dibagikan'
659
+ },
660
+ role: {
661
+ type: 'string',
662
+ enum: ['reader', 'commenter', 'writer'],
663
+ description: 'Peran akses pengguna (default: "reader")'
664
+ },
665
+ type: {
666
+ type: 'string',
667
+ enum: ['anyone', 'user', 'group'],
668
+ description:
669
+ 'Cakupan akses: "anyone" (publik dengan tautan), "user" (spesifik email), atau "group" (default: "anyone")'
670
+ },
671
+ email: {
672
+ type: 'string',
673
+ description: 'Alamat email pengguna jika type adalah "user" atau "group"'
674
+ }
675
+ },
676
+ required: ['file_id'],
677
+ additionalProperties: false
678
+ }
679
+ }
680
+ }
681
+ ]
682
+ },
683
+ google_calendar: {
684
+ description: 'Manajemen jadwal agenda dan event di Google Calendar.',
685
+ tools: [
686
+ {
687
+ type: 'function',
688
+ function: {
689
+ name: 'gcalendar-list',
690
+ description: 'Melihat daftar agenda atau jadwal acara mendatang dari Google Calendar.',
691
+ parameters: {
692
+ type: 'object',
693
+ properties: {
694
+ pagination: { type: 'string', description: 'Rentang data (contoh: "0-10")' },
695
+ time_min: {
696
+ type: 'string',
697
+ description: 'Waktu mulai filter dalam ISO string (contoh: "2026-08-28T00:00:00Z")'
698
+ }
699
+ },
700
+ additionalProperties: false
701
+ }
702
+ }
703
+ },
704
+ {
705
+ type: 'function',
706
+ function: {
707
+ name: 'gcalendar-create',
708
+ description: 'Membuat jadwal atau agenda pertemuan baru di Google Calendar.',
709
+ parameters: {
710
+ type: 'object',
711
+ properties: {
712
+ summary: { type: 'string', description: 'Judul kegiatan atau event' },
713
+ description: { type: 'string', description: 'Deskripsi lengkap kegiatan' },
714
+ start_time: {
715
+ type: 'string',
716
+ description:
717
+ 'Waktu mulai dalam format ISO 8601 (contoh: "2026-08-28T14:00:00+07:00")'
718
+ },
719
+ end_time: {
720
+ type: 'string',
721
+ description:
722
+ 'Waktu selesai dalam format ISO 8601 (contoh: "2026-08-28T15:00:00+07:00")'
723
+ }
724
+ },
725
+ required: ['summary', 'start_time', 'end_time'],
726
+ additionalProperties: false
727
+ }
728
+ }
729
+ },
730
+ {
731
+ type: 'function',
732
+ function: {
733
+ name: 'gcalendar-delete',
734
+ description: 'Menghapus jadwal kegiatan di Google Calendar berdasarkan Event ID.',
735
+ parameters: {
736
+ type: 'object',
737
+ properties: {
738
+ event_id: { type: 'string', description: 'ID event kalender yang akan dihapus' }
739
+ },
740
+ required: ['event_id'],
741
+ additionalProperties: false
742
+ }
743
+ }
744
+ }
745
+ ]
746
+ },
747
+ google_gmail: {
748
+ description: 'Manajemen membaca, mencari, dan mengirim email melalui akun Gmail.',
749
+ tools: [
750
+ {
751
+ type: 'function',
752
+ function: {
753
+ name: 'gmail-search',
754
+ description:
755
+ 'Mencari email di Gmail berdasarkan kata kunci atau filter query Gmail (misal: "is:unread", "from:someone@gmail.com").',
756
+ parameters: {
757
+ type: 'object',
758
+ properties: {
759
+ query: { type: 'string', description: 'Query pencarian Gmail' },
760
+ pagination: { type: 'string', description: 'Rentang data (contoh: "0-10")' }
761
+ },
762
+ required: ['query'],
763
+ additionalProperties: false
764
+ }
765
+ }
766
+ },
767
+ {
768
+ type: 'function',
769
+ function: {
770
+ name: 'gmail-list',
771
+ description: 'Melihat daftar email terbaru di kotak masuk (inbox).',
772
+ parameters: {
773
+ type: 'object',
774
+ properties: {
775
+ pagination: { type: 'string', description: 'Rentang data (contoh: "0-10")' }
776
+ },
777
+ additionalProperties: false
778
+ }
779
+ }
780
+ },
781
+ {
782
+ type: 'function',
783
+ function: {
784
+ name: 'gmail-read',
785
+ description: 'Membaca detail isi pesan email berdasarkan Message ID.',
786
+ parameters: {
787
+ type: 'object',
788
+ properties: {
789
+ message_id: { type: 'string', description: 'ID pesan email' }
790
+ },
791
+ required: ['message_id'],
792
+ additionalProperties: false
793
+ }
794
+ }
795
+ },
796
+ {
797
+ type: 'function',
798
+ function: {
799
+ name: 'gmail-send',
800
+ description: 'Mengirim email baru ke penerima melalui akun Gmail yang terhubung.',
801
+ parameters: {
802
+ type: 'object',
803
+ properties: {
804
+ to: { type: 'string', description: 'Alamat email tujuan' },
805
+ subject: { type: 'string', description: 'Subjek email' },
806
+ body: { type: 'string', description: 'Isi pesan email' }
807
+ },
808
+ required: ['to', 'subject', 'body'],
809
+ additionalProperties: false
810
+ }
811
+ }
812
+ },
813
+ {
814
+ type: 'function',
815
+ function: {
816
+ name: 'gmail-mark-read',
817
+ description: 'Menandai pesan email sebagai sudah dibaca (read) berdasarkan Message ID.',
818
+ parameters: {
819
+ type: 'object',
820
+ properties: {
821
+ message_id: { type: 'string', description: 'ID pesan email' }
822
+ },
823
+ required: ['message_id'],
824
+ additionalProperties: false
825
+ }
826
+ }
827
+ }
828
+ ]
829
+ },
830
+ system_vision_tg: {
831
+ description:
832
+ 'Integrasi sistem vision layar desktop, webcam, output suara lisan (TTS), dan integrasi perpesanan Telegram Bot.',
833
+ tools: [
834
+ {
835
+ type: 'function',
836
+ function: {
837
+ name: 'read-image',
838
+ description:
839
+ 'Membaca berkas gambar lokal (.png, .jpg, .jpeg, .webp, .gif, dll.) dari workspace atau komputer pengguna dan menganalisis tampilan visualnya menggunakan AI Vision.',
840
+ parameters: {
841
+ type: 'object',
842
+ properties: {
843
+ file_path: {
844
+ type: 'string',
845
+ description: 'Path berkas gambar lokal (absolut atau relatif terhadap workspace)'
846
+ },
847
+ query: {
848
+ type: 'string',
849
+ description:
850
+ 'Instruksi atau pertanyaan tentang apa yang ingin kamu analisis dari gambar (opsional)'
851
+ }
852
+ },
853
+ required: ['file_path'],
854
+ additionalProperties: false
855
+ }
856
+ }
857
+ },
858
+ {
859
+ type: 'function',
860
+ function: {
861
+ name: 'analyze-screen',
862
+ description:
863
+ 'Mengambil screenshot seluruh monitor/layar Windows saat ini dan menganalisis tampilan visual antarmuka/aplikasi menggunakan AI Vision.',
864
+ parameters: {
865
+ type: 'object',
866
+ properties: {
867
+ query: {
868
+ type: 'string',
869
+ description:
870
+ 'Instruksi atau pertanyaan tentang apa yang ingin kamu lihat atau analisis dari layar pengguna'
871
+ }
872
+ },
873
+ required: ['query'],
874
+ additionalProperties: false
875
+ }
876
+ }
877
+ },
878
+ {
879
+ type: 'function',
880
+ function: {
881
+ name: 'camera-look',
882
+ description:
883
+ 'Mengambil frame gambar dari webcam/kamera laptop/PC pengguna dan menganalisis apa yang terlihat di depan kamera secara real-time menggunakan AI Vision.',
884
+ parameters: {
885
+ type: 'object',
886
+ properties: {
887
+ query: {
888
+ type: 'string',
889
+ description:
890
+ 'Instruksi atau pertanyaan tentang apa yang ingin kamu lihat dari kamera'
891
+ }
892
+ },
893
+ required: ['query'],
894
+ additionalProperties: false
895
+ }
896
+ }
897
+ },
898
+ {
899
+ type: 'function',
900
+ function: {
901
+ name: 'screenshot-to-tg',
902
+ description:
903
+ 'Mengambil screenshot layar PC dan langsung mengirimkannya ke Telegram admin.',
904
+ parameters: {
905
+ type: 'object',
906
+ properties: {},
907
+ additionalProperties: false
908
+ }
909
+ }
910
+ },
911
+ {
912
+ type: 'function',
913
+ function: {
914
+ name: 'tg-send',
915
+ description:
916
+ 'Mengirim pesan teks, gambar/foto, atau berkas ke chat Telegram. Jika chat_id tidak diisi atau bernilai "admin", otomatis dikirim ke akun Telegram admin pemilik MARK.',
917
+ parameters: {
918
+ type: 'object',
919
+ properties: {
920
+ chat_id: {
921
+ type: 'string',
922
+ description:
923
+ 'ID Chat Telegram tujuan. Bersifat opsional; jika dikosongkan atau diisi "admin", otomatis dikirim ke akun Telegram admin pemilik MARK.'
924
+ },
925
+ type: {
926
+ type: 'string',
927
+ enum: ['auto', 'text', 'photo', 'file'],
928
+ description:
929
+ 'Tipe kiriman: "auto" (otomatis deteksi), "text" (pesan teks), "photo" (gambar/foto yang dirender langsung di chat), atau "file" (dokumen berkas)'
930
+ },
931
+ content: {
932
+ type: 'string',
933
+ description:
934
+ 'Isi teks pesan, path berkas lokal (contoh: "C:\\Users\\...\\image.png"), atau URL berkas yang ingin dikirim.'
935
+ },
936
+ caption: {
937
+ type: 'string',
938
+ description: 'Keterangan/caption opsional jika mengirim gambar atau berkas.'
939
+ }
940
+ },
941
+ required: ['content'],
942
+ additionalProperties: false
943
+ }
944
+ }
945
+ },
946
+ {
947
+ type: 'function',
948
+ function: {
949
+ name: 'speak',
950
+ description:
951
+ 'Mengeluarkan suara lisan (Text-to-Speech) lewat speaker komputer secara langsung.',
952
+ parameters: {
953
+ type: 'object',
954
+ properties: {
955
+ text: { type: 'string', description: 'Teks yang ingin diucapkan secara lisan' }
956
+ },
957
+ required: ['text'],
958
+ additionalProperties: false
959
+ }
960
+ }
961
+ }
962
+ ]
963
+ },
964
+ git_vcs: {
965
+ description: 'Manajemen version control Git untuk repositori proyek.',
966
+ tools: [
967
+ {
968
+ type: 'function',
969
+ function: {
970
+ name: 'git-status',
971
+ description: 'Melihat status modifikasi berkas di repositori git.',
972
+ parameters: {
973
+ type: 'object',
974
+ properties: {
975
+ path: { type: 'string', description: 'Path folder repositori' }
976
+ },
977
+ additionalProperties: false
978
+ }
979
+ }
980
+ },
981
+ {
982
+ type: 'function',
983
+ function: {
984
+ name: 'git-diff',
985
+ description: 'Melihat detail perubahan baris kode (git diff).',
986
+ parameters: {
987
+ type: 'object',
988
+ properties: {
989
+ file_path: { type: 'string', description: 'Nama berkas spesifik' }
990
+ },
991
+ additionalProperties: false
992
+ }
993
+ }
994
+ },
995
+ {
996
+ type: 'function',
997
+ function: {
998
+ name: 'git-commit',
999
+ description: 'Membuat checkpoint commit git.',
1000
+ parameters: {
1001
+ type: 'object',
1002
+ properties: {
1003
+ message: { type: 'string', description: 'Pesan commit' }
1004
+ },
1005
+ required: ['message'],
1006
+ additionalProperties: false
1007
+ }
1008
+ }
1009
+ },
1010
+ {
1011
+ type: 'function',
1012
+ function: {
1013
+ name: 'git-revert',
1014
+ description: 'Me-rollback perubahan berkas yang belum di-commit.',
1015
+ parameters: {
1016
+ type: 'object',
1017
+ properties: {
1018
+ file_path: { type: 'string', description: 'Nama berkas yang akan di-revert' }
1019
+ },
1020
+ additionalProperties: false
1021
+ }
1022
+ }
1023
+ }
1024
+ ]
1025
+ },
1026
+ task_terminal: {
1027
+ description:
1028
+ 'Terminal runner latar belakang (non-blocking) untuk menjalankan server dev, unit test, dan proses jangka panjang.',
1029
+ tools: [
1030
+ {
1031
+ type: 'function',
1032
+ function: {
1033
+ name: 'run-task',
1034
+ description: 'Menjalankan server atau proses terminal background.',
1035
+ parameters: {
1036
+ type: 'object',
1037
+ properties: {
1038
+ task_id: { type: 'string', description: 'ID penanda task' },
1039
+ command: { type: 'string', description: 'Perintah shell terminal' }
1040
+ },
1041
+ required: ['task_id', 'command'],
1042
+ additionalProperties: false
1043
+ }
1044
+ }
1045
+ },
1046
+ {
1047
+ type: 'function',
1048
+ function: {
1049
+ name: 'read-task-output',
1050
+ description: 'Membaca log output terbaru dari background terminal task.',
1051
+ parameters: {
1052
+ type: 'object',
1053
+ properties: {
1054
+ task_id: { type: 'string', description: 'ID penanda task' },
1055
+ lines: { type: 'number', description: 'Jumlah baris log terbaru' }
1056
+ },
1057
+ required: ['task_id'],
1058
+ additionalProperties: false
1059
+ }
1060
+ }
1061
+ },
1062
+ {
1063
+ type: 'function',
1064
+ function: {
1065
+ name: 'kill-task',
1066
+ description: 'Menghentikan proses background terminal yang sedang berjalan.',
1067
+ parameters: {
1068
+ type: 'object',
1069
+ properties: {
1070
+ task_id: { type: 'string', description: 'ID penanda task yang akan dihentikan' }
1071
+ },
1072
+ required: ['task_id'],
1073
+ additionalProperties: false
1074
+ }
1075
+ }
1076
+ },
1077
+ {
1078
+ type: 'function',
1079
+ function: {
1080
+ name: 'list-tasks',
1081
+ description: 'Melihat seluruh background tasks yang sedang berjalan.',
1082
+ parameters: {
1083
+ type: 'object',
1084
+ properties: {},
1085
+ additionalProperties: false
1086
+ }
1087
+ }
1088
+ }
1089
+ ]
1090
+ },
1091
+ custom_plugins: {
1092
+ description:
1093
+ 'Custom plugin dan modul ekstensi JavaScript lokal buatan pengguna (Documents/Mark Plugins).',
1094
+ tools: [
1095
+ {
1096
+ type: 'function',
1097
+ function: {
1098
+ name: 'list-plugins',
1099
+ description:
1100
+ 'Melihat daftar seluruh custom plugin lokal yang terinstall beserta action/sub-tool di dalamnya dan status aktifnya.',
1101
+ parameters: {
1102
+ type: 'object',
1103
+ properties: {},
1104
+ additionalProperties: false
1105
+ }
1106
+ }
1107
+ }
1108
+ ]
1109
+ }
1110
+ }
1111
+
1112
+ export const GROUP_TOOL_GROUP_NAMES = Object.keys(GROUP_TOOLS_SCHEMA)
1113
+
1114
+ export const GROUP_TOOL_DESCRIPTIONS = Object.fromEntries(
1115
+ Object.entries(GROUP_TOOLS_SCHEMA).map(([key, group]) => [key, group.description])
1116
+ )
1117
+
1118
+ // Injeksi parameter reason ke seluruh tool schema di GROUP_TOOLS_SCHEMA
1119
+ for (const group of Object.values(GROUP_TOOLS_SCHEMA)) {
1120
+ if (Array.isArray(group.tools)) {
1121
+ for (const t of group.tools) {
1122
+ if (t.function?.parameters?.properties) {
1123
+ if (!t.function.parameters.properties.reason) {
1124
+ t.function.parameters.properties.reason = {
1125
+ type: 'string',
1126
+ description:
1127
+ 'Penjelasan ringkas dalam bahasa manusia mengenai alasan atau tujuan aksi ini (contoh: "Membuka tab Instagram di browser").'
1128
+ }
1129
+ }
1130
+ if (Array.isArray(t.function.parameters.required)) {
1131
+ if (!t.function.parameters.required.includes('reason')) {
1132
+ t.function.parameters.required.push('reason')
1133
+ }
1134
+ } else {
1135
+ t.function.parameters.required = ['reason']
1136
+ }
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+
1142
+ // Legacy dictionary representation for backwards-compatibility
1143
+ export const GROUP_TOOLS_DEFINITION = Object.entries(GROUP_TOOLS_SCHEMA).reduce(
1144
+ (acc, [groupKey, group]) => {
1145
+ acc[groupKey] = {
1146
+ description: group.description,
1147
+ tools: group.tools.reduce((tAcc, t) => {
1148
+ tAcc[t.function.name] = t.function.description
1149
+ return tAcc
1150
+ }, {})
1151
+ }
1152
+ return acc
1153
+ },
1154
+ {}
1155
+ )
1156
+
1157
+ export const group_tools = async () => {
1158
+ return GROUP_TOOLS_DEFINITION
1159
+ }
1160
+
1161
+ export const group_tools_flat = {}
1162
+ for (const group of Object.values(GROUP_TOOLS_DEFINITION)) {
1163
+ Object.assign(group_tools_flat, group.tools)
1164
+ }