@dotsetlabs/dotclaw 1.8.0 → 2.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 (175) hide show
  1. package/.env.example +6 -0
  2. package/README.md +14 -7
  3. package/config-examples/groups/global/CLAUDE.md +6 -14
  4. package/config-examples/groups/main/CLAUDE.md +8 -39
  5. package/config-examples/runtime.json +4 -4
  6. package/container/Dockerfile +20 -2
  7. package/container/agent-runner/package-lock.json +260 -2
  8. package/container/agent-runner/package.json +2 -1
  9. package/container/agent-runner/src/agent-config.ts +57 -8
  10. package/container/agent-runner/src/browser.ts +180 -0
  11. package/container/agent-runner/src/container-protocol.ts +5 -0
  12. package/container/agent-runner/src/id.ts +3 -2
  13. package/container/agent-runner/src/index.ts +184 -390
  14. package/container/agent-runner/src/ipc.ts +33 -1
  15. package/container/agent-runner/src/mcp-client.ts +222 -0
  16. package/container/agent-runner/src/mcp-registry.ts +163 -0
  17. package/container/agent-runner/src/skill-loader.ts +375 -0
  18. package/container/agent-runner/src/tools.ts +260 -32
  19. package/container/agent-runner/src/tts.ts +61 -0
  20. package/container/agent-runner/tsconfig.json +1 -0
  21. package/dist/admin-commands.d.ts.map +1 -1
  22. package/dist/admin-commands.js +12 -0
  23. package/dist/admin-commands.js.map +1 -1
  24. package/dist/agent-execution.d.ts +3 -1
  25. package/dist/agent-execution.d.ts.map +1 -1
  26. package/dist/agent-execution.js +21 -0
  27. package/dist/agent-execution.js.map +1 -1
  28. package/dist/background-job-classifier.d.ts +1 -1
  29. package/dist/background-job-classifier.d.ts.map +1 -1
  30. package/dist/background-jobs.d.ts.map +1 -1
  31. package/dist/background-jobs.js +30 -10
  32. package/dist/background-jobs.js.map +1 -1
  33. package/dist/cli.js +61 -16
  34. package/dist/cli.js.map +1 -1
  35. package/dist/config.d.ts +0 -2
  36. package/dist/config.d.ts.map +1 -1
  37. package/dist/config.js +1 -3
  38. package/dist/config.js.map +1 -1
  39. package/dist/container-protocol.d.ts +5 -0
  40. package/dist/container-protocol.d.ts.map +1 -1
  41. package/dist/container-runner.d.ts.map +1 -1
  42. package/dist/container-runner.js +33 -14
  43. package/dist/container-runner.js.map +1 -1
  44. package/dist/dashboard.d.ts +5 -0
  45. package/dist/dashboard.d.ts.map +1 -1
  46. package/dist/dashboard.js +11 -5
  47. package/dist/dashboard.js.map +1 -1
  48. package/dist/db.d.ts +0 -13
  49. package/dist/db.d.ts.map +1 -1
  50. package/dist/db.js +41 -70
  51. package/dist/db.js.map +1 -1
  52. package/dist/error-messages.d.ts.map +1 -1
  53. package/dist/error-messages.js +13 -5
  54. package/dist/error-messages.js.map +1 -1
  55. package/dist/hooks.d.ts +7 -0
  56. package/dist/hooks.d.ts.map +1 -0
  57. package/dist/hooks.js +93 -0
  58. package/dist/hooks.js.map +1 -0
  59. package/dist/id.d.ts.map +1 -1
  60. package/dist/id.js +2 -1
  61. package/dist/id.js.map +1 -1
  62. package/dist/index.js +742 -2793
  63. package/dist/index.js.map +1 -1
  64. package/dist/ipc-dispatcher.d.ts +26 -0
  65. package/dist/ipc-dispatcher.d.ts.map +1 -0
  66. package/dist/ipc-dispatcher.js +1044 -0
  67. package/dist/ipc-dispatcher.js.map +1 -0
  68. package/dist/local-embeddings.d.ts +7 -0
  69. package/dist/local-embeddings.d.ts.map +1 -0
  70. package/dist/local-embeddings.js +60 -0
  71. package/dist/local-embeddings.js.map +1 -0
  72. package/dist/maintenance.d.ts.map +1 -1
  73. package/dist/maintenance.js +7 -1
  74. package/dist/maintenance.js.map +1 -1
  75. package/dist/memory-embeddings.d.ts +1 -1
  76. package/dist/memory-embeddings.d.ts.map +1 -1
  77. package/dist/memory-embeddings.js +59 -31
  78. package/dist/memory-embeddings.js.map +1 -1
  79. package/dist/memory-store.d.ts +0 -10
  80. package/dist/memory-store.d.ts.map +1 -1
  81. package/dist/memory-store.js +12 -28
  82. package/dist/memory-store.js.map +1 -1
  83. package/dist/message-pipeline.d.ts +47 -0
  84. package/dist/message-pipeline.d.ts.map +1 -0
  85. package/dist/message-pipeline.js +876 -0
  86. package/dist/message-pipeline.js.map +1 -0
  87. package/dist/metrics.d.ts +8 -8
  88. package/dist/metrics.d.ts.map +1 -1
  89. package/dist/metrics.js.map +1 -1
  90. package/dist/model-registry.d.ts +0 -14
  91. package/dist/model-registry.d.ts.map +1 -1
  92. package/dist/model-registry.js +0 -36
  93. package/dist/model-registry.js.map +1 -1
  94. package/dist/orchestration.d.ts +39 -0
  95. package/dist/orchestration.d.ts.map +1 -0
  96. package/dist/orchestration.js +136 -0
  97. package/dist/orchestration.js.map +1 -0
  98. package/dist/paths.d.ts.map +1 -1
  99. package/dist/paths.js +2 -0
  100. package/dist/paths.js.map +1 -1
  101. package/dist/providers/discord/discord-format.d.ts +16 -0
  102. package/dist/providers/discord/discord-format.d.ts.map +1 -0
  103. package/dist/providers/discord/discord-format.js +153 -0
  104. package/dist/providers/discord/discord-format.js.map +1 -0
  105. package/dist/providers/discord/discord-provider.d.ts +50 -0
  106. package/dist/providers/discord/discord-provider.d.ts.map +1 -0
  107. package/dist/providers/discord/discord-provider.js +604 -0
  108. package/dist/providers/discord/discord-provider.js.map +1 -0
  109. package/dist/providers/discord/index.d.ts +4 -0
  110. package/dist/providers/discord/index.d.ts.map +1 -0
  111. package/dist/providers/discord/index.js +3 -0
  112. package/dist/providers/discord/index.js.map +1 -0
  113. package/dist/providers/registry.d.ts +14 -0
  114. package/dist/providers/registry.d.ts.map +1 -0
  115. package/dist/providers/registry.js +49 -0
  116. package/dist/providers/registry.js.map +1 -0
  117. package/dist/providers/telegram/index.d.ts +4 -0
  118. package/dist/providers/telegram/index.d.ts.map +1 -0
  119. package/dist/providers/telegram/index.js +3 -0
  120. package/dist/providers/telegram/index.js.map +1 -0
  121. package/dist/providers/telegram/telegram-format.d.ts +3 -0
  122. package/dist/providers/telegram/telegram-format.d.ts.map +1 -0
  123. package/dist/providers/telegram/telegram-format.js +215 -0
  124. package/dist/providers/telegram/telegram-format.js.map +1 -0
  125. package/dist/providers/telegram/telegram-provider.d.ts +51 -0
  126. package/dist/providers/telegram/telegram-provider.d.ts.map +1 -0
  127. package/dist/providers/telegram/telegram-provider.js +824 -0
  128. package/dist/providers/telegram/telegram-provider.js.map +1 -0
  129. package/dist/providers/types.d.ts +107 -0
  130. package/dist/providers/types.d.ts.map +1 -0
  131. package/dist/providers/types.js +2 -0
  132. package/dist/providers/types.js.map +1 -0
  133. package/dist/request-router.d.ts.map +1 -1
  134. package/dist/request-router.js +12 -26
  135. package/dist/request-router.js.map +1 -1
  136. package/dist/runtime-config.d.ts +70 -6
  137. package/dist/runtime-config.d.ts.map +1 -1
  138. package/dist/runtime-config.js +119 -65
  139. package/dist/runtime-config.js.map +1 -1
  140. package/dist/skill-manager.d.ts +39 -0
  141. package/dist/skill-manager.d.ts.map +1 -0
  142. package/dist/skill-manager.js +286 -0
  143. package/dist/skill-manager.js.map +1 -0
  144. package/dist/task-scheduler.d.ts.map +1 -1
  145. package/dist/task-scheduler.js +56 -11
  146. package/dist/task-scheduler.js.map +1 -1
  147. package/dist/telegram-format.d.ts.map +1 -1
  148. package/dist/telegram-format.js +16 -1
  149. package/dist/telegram-format.js.map +1 -1
  150. package/dist/tool-intent-probe.d.ts +11 -0
  151. package/dist/tool-intent-probe.d.ts.map +1 -0
  152. package/dist/tool-intent-probe.js +63 -0
  153. package/dist/tool-intent-probe.js.map +1 -0
  154. package/dist/tool-policy.d.ts.map +1 -1
  155. package/dist/tool-policy.js +18 -0
  156. package/dist/tool-policy.js.map +1 -1
  157. package/dist/transcription.d.ts +8 -0
  158. package/dist/transcription.d.ts.map +1 -0
  159. package/dist/transcription.js +174 -0
  160. package/dist/transcription.js.map +1 -0
  161. package/dist/types.d.ts +2 -9
  162. package/dist/types.d.ts.map +1 -1
  163. package/dist/workflow-engine.d.ts +51 -0
  164. package/dist/workflow-engine.d.ts.map +1 -0
  165. package/dist/workflow-engine.js +281 -0
  166. package/dist/workflow-engine.js.map +1 -0
  167. package/dist/workflow-store.d.ts +39 -0
  168. package/dist/workflow-store.d.ts.map +1 -0
  169. package/dist/workflow-store.js +173 -0
  170. package/dist/workflow-store.js.map +1 -0
  171. package/package.json +15 -3
  172. package/scripts/bootstrap.js +40 -4
  173. package/scripts/configure.js +48 -7
  174. package/scripts/doctor.js +30 -4
  175. package/scripts/init.js +13 -6
@@ -7,6 +7,7 @@ import { tool as sdkTool, type Tool } from '@openrouter/sdk';
7
7
  import { z } from 'zod';
8
8
  import { createIpcHandlers, IpcContext } from './ipc.js';
9
9
  import type { AgentRuntimeConfig } from './agent-config.js';
10
+ import { collectSkillPluginDirs } from './skill-loader.js';
10
11
 
11
12
  type ToolConfig = {
12
13
  name: string;
@@ -66,9 +67,14 @@ function buildToolRuntime(config: AgentRuntimeConfig['agent']): ToolRuntime {
66
67
  const webfetchBlocklist = (config.tools.webfetch.blocklist || [])
67
68
  .map(normalizeDomain)
68
69
  .filter(Boolean);
70
+ const skillPluginDirs = collectSkillPluginDirs({
71
+ groupDir: WORKSPACE_GROUP,
72
+ globalDir: WORKSPACE_GLOBAL
73
+ });
69
74
  const pluginDirs = Array.from(new Set([
70
75
  ...config.tools.plugin.dirs,
71
- ...DEFAULT_PLUGIN_DIRS
76
+ ...DEFAULT_PLUGIN_DIRS,
77
+ ...skillPluginDirs
72
78
  ]));
73
79
  const toolSummaryTools = (config.tools.toolSummary.tools || [])
74
80
  .map(toolName => toolName.trim().toLowerCase())
@@ -463,7 +469,7 @@ function interpolateTemplate(value: string, args: Record<string, unknown>): stri
463
469
  });
464
470
  }
465
471
 
466
- function shellEscape(value: string): string {
472
+ export function shellEscape(value: string): string {
467
473
  return `'${value.replace(/'/g, `'\\''`)}'`;
468
474
  }
469
475
 
@@ -1018,7 +1024,7 @@ export function createTools(
1018
1024
 
1019
1025
  const bashTool = tool({
1020
1026
  name: 'Bash',
1021
- description: 'Run a shell command inside the container. CWD is /workspace/group.',
1027
+ description: 'Run a shell command inside the container. Working directory is /workspace/group. Output is captured (no interactive commands). Use for ffmpeg, git, system tools, etc.',
1022
1028
  inputSchema: z.object({
1023
1029
  command: z.string().describe('Command to run'),
1024
1030
  timeoutMs: z.number().int().positive().optional().describe('Timeout in milliseconds')
@@ -1037,7 +1043,7 @@ export function createTools(
1037
1043
 
1038
1044
  const pythonTool = tool({
1039
1045
  name: 'Python',
1040
- description: 'Execute Python code in a sandboxed environment. Available packages: pandas, numpy, requests, beautifulsoup4, matplotlib. CWD is /workspace/group.',
1046
+ description: 'Execute Python code. Available packages: pandas, numpy, requests, beautifulsoup4, matplotlib, Pillow, openpyxl, pyyaml, tabulate, chardet. CWD is /workspace/group. For charts: use plt.savefig() then send_photo (never plt.show()).',
1041
1047
  inputSchema: z.object({
1042
1048
  code: z.string().describe('Python code to execute'),
1043
1049
  timeoutMs: z.number().int().positive().optional().describe('Timeout in milliseconds (default 30000)')
@@ -1054,7 +1060,7 @@ export function createTools(
1054
1060
  const tempFile = path.join(WORKSPACE_GROUP, `.tmp_script_${Date.now()}_${Math.random().toString(36).slice(2)}.py`);
1055
1061
  fs.writeFileSync(tempFile, code);
1056
1062
  try {
1057
- const result = await runCommand(`python3 ${tempFile}`, timeoutMs || 30000, runtime.bashOutputLimitBytes);
1063
+ const result = await runCommand(`python3 ${shellEscape(tempFile)}`, timeoutMs || 30000, runtime.bashOutputLimitBytes);
1058
1064
  return result;
1059
1065
  } finally {
1060
1066
  try {
@@ -1249,7 +1255,7 @@ export function createTools(
1249
1255
 
1250
1256
  const grepTool = tool({
1251
1257
  name: 'Grep',
1252
- description: 'Search for a pattern in files.',
1258
+ description: 'Search for a text pattern in files. Returns matching lines with file paths and line numbers.',
1253
1259
  inputSchema: z.object({
1254
1260
  pattern: z.string().describe('Search pattern (plain text or regex)'),
1255
1261
  path: z.string().optional().describe('File or directory path (default /workspace/group)'),
@@ -1542,17 +1548,17 @@ export function createTools(
1542
1548
  return null;
1543
1549
  }).filter(Boolean) as Tool[];
1544
1550
 
1545
- const requiredTelegramText = z.string().trim().min(1);
1546
- const requiredTelegramSingleMessageText = z.string().trim().min(1).max(4096);
1547
- const optionalTelegramCaption = z.string().trim().min(1).max(1024).optional();
1551
+ const requiredMessageText = z.string().trim().min(1);
1552
+ const requiredSingleMessageText = z.string().trim().min(1).max(4096);
1553
+ const optionalCaption = z.string().trim().min(1).max(1024).optional();
1548
1554
  const requiredWorkspacePath = z.string().trim().min(1);
1549
1555
  const optionalNameField = z.string().trim().min(1).max(128).optional();
1550
1556
 
1551
1557
  const sendMessageTool = tool({
1552
1558
  name: 'mcp__dotclaw__send_message',
1553
- description: 'Send a message to the current Telegram chat.',
1559
+ description: 'Send a message to the current chat.',
1554
1560
  inputSchema: z.object({
1555
- text: requiredTelegramText.describe('The message text to send'),
1561
+ text: requiredMessageText.describe('The message text to send'),
1556
1562
  reply_to_message_id: z.number().int().positive().optional().describe('Message ID to reply to')
1557
1563
  }),
1558
1564
  outputSchema: z.object({
@@ -1565,10 +1571,10 @@ export function createTools(
1565
1571
 
1566
1572
  const sendFileTool = tool({
1567
1573
  name: 'mcp__dotclaw__send_file',
1568
- description: 'Send a file/document to the current Telegram chat. The file must exist under /workspace/group.',
1574
+ description: 'Send a file/document to the current chat. The file must exist under /workspace/group.',
1569
1575
  inputSchema: z.object({
1570
1576
  path: requiredWorkspacePath.describe('File path (relative to /workspace/group or absolute under /workspace/group)'),
1571
- caption: optionalTelegramCaption.describe('Optional caption text'),
1577
+ caption: optionalCaption.describe('Optional caption text'),
1572
1578
  reply_to_message_id: z.number().int().positive().optional().describe('Message ID to reply to')
1573
1579
  }),
1574
1580
  outputSchema: z.object({
@@ -1584,10 +1590,10 @@ export function createTools(
1584
1590
 
1585
1591
  const sendPhotoTool = tool({
1586
1592
  name: 'mcp__dotclaw__send_photo',
1587
- description: 'Send a photo/image to the current Telegram chat with compression. The file must exist under /workspace/group.',
1593
+ description: 'Send a photo/image to the current chat with compression. The file must exist under /workspace/group.',
1588
1594
  inputSchema: z.object({
1589
1595
  path: requiredWorkspacePath.describe('Image file path (relative to /workspace/group or absolute under /workspace/group)'),
1590
- caption: optionalTelegramCaption.describe('Optional caption text'),
1596
+ caption: optionalCaption.describe('Optional caption text'),
1591
1597
  reply_to_message_id: z.number().int().positive().optional().describe('Message ID to reply to')
1592
1598
  }),
1593
1599
  outputSchema: z.object({
@@ -1603,10 +1609,10 @@ export function createTools(
1603
1609
 
1604
1610
  const sendVoiceTool = tool({
1605
1611
  name: 'mcp__dotclaw__send_voice',
1606
- description: 'Send a voice message to the current Telegram chat. File must be .ogg format with Opus codec.',
1612
+ description: 'Send a voice message to the current chat. File must be .ogg format with Opus codec.',
1607
1613
  inputSchema: z.object({
1608
1614
  path: requiredWorkspacePath.describe('Voice file path (relative to /workspace/group or absolute under /workspace/group)'),
1609
- caption: optionalTelegramCaption.describe('Optional caption text'),
1615
+ caption: optionalCaption.describe('Optional caption text'),
1610
1616
  duration: z.number().int().positive().optional().describe('Duration in seconds'),
1611
1617
  reply_to_message_id: z.number().int().positive().optional().describe('Message ID to reply to')
1612
1618
  }),
@@ -1620,12 +1626,43 @@ export function createTools(
1620
1626
  })
1621
1627
  });
1622
1628
 
1629
+ const textToSpeechTool = tool({
1630
+ name: 'mcp__dotclaw__text_to_speech',
1631
+ description: 'Convert text to speech and send as a voice message. Generates an .ogg voice note from text using TTS.',
1632
+ inputSchema: z.object({
1633
+ text: z.string().min(1).max(4096).describe('Text to convert to speech'),
1634
+ voice: z.string().optional().describe('Voice ID for Edge TTS (e.g., "en-US-AriaNeural", "en-US-GuyNeural", "en-GB-SoniaNeural")'),
1635
+ language: z.string().optional().describe('Language code (e.g., "en", "es", "fr")'),
1636
+ send: z.boolean().optional().describe('Whether to send immediately as voice message (default: true)')
1637
+ }),
1638
+ outputSchema: z.object({
1639
+ ok: z.boolean(),
1640
+ path: z.string().optional(),
1641
+ id: z.string().optional(),
1642
+ error: z.string().optional()
1643
+ }),
1644
+ execute: wrapExecute('mcp__dotclaw__text_to_speech', async ({ text, voice, language, send }: { text: string; voice?: string; language?: string; send?: boolean }) => {
1645
+ try {
1646
+ const { synthesizeSpeech } = await import('./tts.js');
1647
+ const outputPath = await synthesizeSpeech(text, { voice, language });
1648
+ if (send !== false) {
1649
+ const resolved = resolveGroupPath(outputPath, true);
1650
+ await ipc.sendVoice({ path: resolved });
1651
+ return { ok: true, path: outputPath };
1652
+ }
1653
+ return { ok: true, path: outputPath };
1654
+ } catch (err) {
1655
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
1656
+ }
1657
+ })
1658
+ });
1659
+
1623
1660
  const sendAudioTool = tool({
1624
1661
  name: 'mcp__dotclaw__send_audio',
1625
- description: 'Send an audio file to the current Telegram chat (mp3, m4a, etc.).',
1662
+ description: 'Send an audio file to the current chat (mp3, m4a, etc.).',
1626
1663
  inputSchema: z.object({
1627
1664
  path: requiredWorkspacePath.describe('Audio file path (relative to /workspace/group or absolute under /workspace/group)'),
1628
- caption: optionalTelegramCaption.describe('Optional caption text'),
1665
+ caption: optionalCaption.describe('Optional caption text'),
1629
1666
  duration: z.number().int().positive().optional().describe('Duration in seconds'),
1630
1667
  performer: optionalNameField.describe('Audio performer/artist'),
1631
1668
  title: optionalNameField.describe('Audio title'),
@@ -1643,7 +1680,7 @@ export function createTools(
1643
1680
 
1644
1681
  const sendLocationTool = tool({
1645
1682
  name: 'mcp__dotclaw__send_location',
1646
- description: 'Send a location pin to the current Telegram chat.',
1683
+ description: 'Send a location pin to the current chat.',
1647
1684
  inputSchema: z.object({
1648
1685
  latitude: z.number().min(-90).max(90).describe('Latitude'),
1649
1686
  longitude: z.number().min(-180).max(180).describe('Longitude'),
@@ -1659,7 +1696,7 @@ export function createTools(
1659
1696
 
1660
1697
  const sendContactTool = tool({
1661
1698
  name: 'mcp__dotclaw__send_contact',
1662
- description: 'Send a contact card to the current Telegram chat.',
1699
+ description: 'Send a contact card to the current chat.',
1663
1700
  inputSchema: z.object({
1664
1701
  phone_number: z.string().trim().min(1).max(64).describe('Phone number with country code'),
1665
1702
  first_name: z.string().trim().min(1).max(64).describe('First name'),
@@ -1676,7 +1713,7 @@ export function createTools(
1676
1713
 
1677
1714
  const sendPollTool = tool({
1678
1715
  name: 'mcp__dotclaw__send_poll',
1679
- description: 'Create a Telegram poll in the current chat.',
1716
+ description: 'Create a poll in the current chat.',
1680
1717
  inputSchema: z.object({
1681
1718
  question: z.string().trim().min(1).max(300).describe('Poll question'),
1682
1719
  options: z.array(z.string().trim().min(1).max(100)).min(2).max(10).describe('Poll options (2-10)'),
@@ -1735,7 +1772,7 @@ export function createTools(
1735
1772
  name: 'mcp__dotclaw__send_buttons',
1736
1773
  description: 'Send a message with inline keyboard buttons. Each button can be a URL link or a callback button.',
1737
1774
  inputSchema: z.object({
1738
- text: requiredTelegramSingleMessageText.describe('Message text above the buttons'),
1775
+ text: requiredSingleMessageText.describe('Message text above the buttons'),
1739
1776
  buttons: z.array(z.array(z.object({
1740
1777
  text: z.string().trim().min(1).max(64).describe('Button label'),
1741
1778
  url: z.string().trim().min(1).optional().describe('URL to open (for link buttons)'),
@@ -1785,7 +1822,7 @@ export function createTools(
1785
1822
  description: 'Edit a previously sent message by message ID.',
1786
1823
  inputSchema: z.object({
1787
1824
  message_id: z.number().int().positive().describe('The message ID to edit'),
1788
- text: requiredTelegramSingleMessageText.describe('New message text'),
1825
+ text: requiredSingleMessageText.describe('New message text'),
1789
1826
  chat_jid: z.string().optional().describe('Target chat ID (defaults to current chat)')
1790
1827
  }),
1791
1828
  outputSchema: z.object({
@@ -1894,11 +1931,11 @@ export function createTools(
1894
1931
 
1895
1932
  const scheduleTaskTool = tool({
1896
1933
  name: 'mcp__dotclaw__schedule_task',
1897
- description: 'Schedule a recurring or one-time task.',
1934
+ description: 'Schedule a recurring or one-time task. For cron: use 5-field expressions (min hour dom mon dow), e.g. "0 9 * * 1-5" = weekdays at 9am. For interval: milliseconds, e.g. "3600000" = every hour. For once: ISO 8601 timestamp.',
1898
1935
  inputSchema: z.object({
1899
- prompt: z.string().describe('Task prompt'),
1936
+ prompt: z.string().describe('What the task should do when it runs'),
1900
1937
  schedule_type: z.enum(['cron', 'interval', 'once']),
1901
- schedule_value: z.string(),
1938
+ schedule_value: z.string().describe('Cron expression, interval ms, or ISO timestamp'),
1902
1939
  timezone: z.string().optional().describe('Optional IANA timezone (e.g., America/New_York)'),
1903
1940
  context_mode: z.enum(['group', 'isolated']).optional(),
1904
1941
  target_group: z.string().optional()
@@ -1996,7 +2033,7 @@ export function createTools(
1996
2033
 
1997
2034
  const spawnJobTool = tool({
1998
2035
  name: 'mcp__dotclaw__spawn_job',
1999
- description: 'Start a background job that runs asynchronously and reports results later.',
2036
+ description: 'Start a long-running background job. Use only for tasks that take >2 minutes (deep research, large code projects). Quick tasks should run in the foreground. context_mode "group" shares the workspace; "isolated" gets a clean environment.',
2000
2037
  inputSchema: z.object({
2001
2038
  prompt: z.string(),
2002
2039
  context_mode: z.enum(['group', 'isolated']).optional(),
@@ -2089,9 +2126,101 @@ export function createTools(
2089
2126
  ipc.jobUpdate(args))
2090
2127
  });
2091
2128
 
2129
+ const orchestrateTool = tool({
2130
+ name: 'mcp__dotclaw__orchestrate',
2131
+ description: 'Run multiple sub-tasks in parallel and aggregate results. Each task runs as an independent background job. Use for research, analysis, or any task that can be decomposed into parallel parts.',
2132
+ inputSchema: z.object({
2133
+ tasks: z.array(z.object({
2134
+ name: z.string().describe('Short name for this sub-task'),
2135
+ prompt: z.string().describe('Full prompt for the sub-task'),
2136
+ model_override: z.string().optional(),
2137
+ timeout_ms: z.number().optional(),
2138
+ tool_allow: z.array(z.string()).optional(),
2139
+ tool_deny: z.array(z.string()).optional()
2140
+ })).min(1).max(10),
2141
+ max_concurrent: z.number().int().min(1).max(10).optional().describe('Max parallel tasks (default: all)'),
2142
+ timeout_ms: z.number().optional().describe('Overall timeout in ms (default: 600000)'),
2143
+ aggregation_prompt: z.string().optional().describe('Optional prompt to synthesize all results into a final answer')
2144
+ }),
2145
+ outputSchema: z.object({
2146
+ ok: z.boolean(),
2147
+ result: z.any().optional(),
2148
+ error: z.string().optional()
2149
+ }),
2150
+ execute: wrapExecute('mcp__dotclaw__orchestrate', async (args: {
2151
+ tasks: Array<{ name: string; prompt: string; model_override?: string; timeout_ms?: number; tool_allow?: string[]; tool_deny?: string[] }>;
2152
+ max_concurrent?: number;
2153
+ timeout_ms?: number;
2154
+ aggregation_prompt?: string;
2155
+ }) => ipc.orchestrate(args))
2156
+ });
2157
+
2158
+ // ─── Workflow Tools ────────────────────────────────────────
2159
+
2160
+ const workflowStartTool = tool({
2161
+ name: 'mcp__dotclaw__workflow_start',
2162
+ description: 'Start a named workflow. Workflows are YAML/JSON definitions in the group workflows/ directory with multi-step execution, dependency graphs, and state passing between steps.',
2163
+ inputSchema: z.object({
2164
+ name: z.string().describe('Workflow name (matches filename without extension in workflows/ directory)'),
2165
+ params: z.record(z.string(), z.any()).optional().describe('Optional parameters to pass to the workflow')
2166
+ }),
2167
+ outputSchema: z.object({
2168
+ ok: z.boolean(),
2169
+ run_id: z.string().optional(),
2170
+ error: z.string().optional()
2171
+ }),
2172
+ execute: wrapExecute('mcp__dotclaw__workflow_start', async (args: { name: string; params?: Record<string, unknown> }) =>
2173
+ ipc.workflowStart(args))
2174
+ });
2175
+
2176
+ const workflowStatusTool = tool({
2177
+ name: 'mcp__dotclaw__workflow_status',
2178
+ description: 'Get the status of a workflow run including all step results.',
2179
+ inputSchema: z.object({
2180
+ run_id: z.string().describe('Workflow run ID (returned by workflow_start)')
2181
+ }),
2182
+ outputSchema: z.object({
2183
+ ok: z.boolean(),
2184
+ result: z.any().optional(),
2185
+ error: z.string().optional()
2186
+ }),
2187
+ execute: wrapExecute('mcp__dotclaw__workflow_status', async (args: { run_id: string }) =>
2188
+ ipc.workflowStatus(args))
2189
+ });
2190
+
2191
+ const workflowCancelTool = tool({
2192
+ name: 'mcp__dotclaw__workflow_cancel',
2193
+ description: 'Cancel a running workflow.',
2194
+ inputSchema: z.object({
2195
+ run_id: z.string().describe('Workflow run ID to cancel')
2196
+ }),
2197
+ outputSchema: z.object({
2198
+ ok: z.boolean(),
2199
+ error: z.string().optional()
2200
+ }),
2201
+ execute: wrapExecute('mcp__dotclaw__workflow_cancel', async (args: { run_id: string }) =>
2202
+ ipc.workflowCancel(args))
2203
+ });
2204
+
2205
+ const workflowListTool = tool({
2206
+ name: 'mcp__dotclaw__workflow_list',
2207
+ description: 'List workflow runs for the current group.',
2208
+ inputSchema: z.object({
2209
+ status: z.string().optional().describe('Filter by status: pending, running, completed, failed, canceled'),
2210
+ limit: z.number().int().min(1).max(50).optional().describe('Max results (default: 10)')
2211
+ }),
2212
+ outputSchema: z.object({
2213
+ ok: z.boolean(),
2214
+ result: z.any().optional(),
2215
+ error: z.string().optional()
2216
+ }),
2217
+ execute: wrapExecute('mcp__dotclaw__workflow_list', async (args: { status?: string; limit?: number }) =>
2218
+ ipc.workflowList(args))
2219
+ });
2220
+
2092
2221
  const registerGroupTool = tool({
2093
2222
  name: 'mcp__dotclaw__register_group',
2094
- description: 'Register a new Telegram chat (main group only).',
2223
+ description: 'Register a new chat/channel (main group only).',
2095
2224
  inputSchema: z.object({
2096
2225
  jid: z.string(),
2097
2226
  name: z.string(),
@@ -2108,7 +2237,7 @@ export function createTools(
2108
2237
 
2109
2238
  const removeGroupTool = tool({
2110
2239
  name: 'mcp__dotclaw__remove_group',
2111
- description: 'Remove a registered Telegram chat by chat id, name, or folder (main group only).',
2240
+ description: 'Remove a registered chat/channel by chat id, name, or folder (main group only).',
2112
2241
  inputSchema: z.object({
2113
2242
  identifier: z.string().describe('Chat id, group name, or folder')
2114
2243
  }),
@@ -2150,7 +2279,7 @@ export function createTools(
2150
2279
 
2151
2280
  const memoryUpsertTool = tool({
2152
2281
  name: 'mcp__dotclaw__memory_upsert',
2153
- description: 'Upsert long-term memory items (use for durable user or group facts/preferences).',
2282
+ description: 'Save durable memories (user preferences, facts, project context). Use conflict_key to update existing memories instead of creating duplicates. importance 0-1 controls recall priority.',
2154
2283
  inputSchema: z.object({
2155
2284
  items: z.array(z.object({
2156
2285
  scope: z.enum(['user', 'group', 'global']),
@@ -2216,7 +2345,7 @@ export function createTools(
2216
2345
 
2217
2346
  const memorySearchTool = tool({
2218
2347
  name: 'mcp__dotclaw__memory_search',
2219
- description: 'Search long-term memory items.',
2348
+ description: 'Search stored memories by natural language query. Returns the most relevant matches ranked by similarity and importance.',
2220
2349
  inputSchema: z.object({
2221
2350
  query: z.string(),
2222
2351
  userId: z.string().optional(),
@@ -2248,6 +2377,74 @@ export function createTools(
2248
2377
  ipc.memoryStats(args))
2249
2378
  });
2250
2379
 
2380
+ // --- Browser Tool ---
2381
+ const browserTool = tool({
2382
+ name: 'Browser',
2383
+ description: 'Browser automation tool. Navigate pages, take screenshots, click elements, fill forms, extract content, and run JavaScript. Screenshots are saved to /workspace/group/screenshots/.',
2384
+ inputSchema: z.object({
2385
+ action: z.enum(['navigate', 'snapshot', 'click', 'fill', 'screenshot', 'extract', 'evaluate', 'close']).describe('Browser action to perform'),
2386
+ url: z.string().optional().describe('URL to navigate to (for navigate action)'),
2387
+ ref: z.string().optional().describe('Element reference from snapshot (for click/fill actions)'),
2388
+ text: z.string().optional().describe('Text to fill (for fill action)'),
2389
+ selector: z.string().optional().describe('CSS selector (for extract action)'),
2390
+ js: z.string().optional().describe('JavaScript to evaluate (for evaluate action)'),
2391
+ fullPage: z.boolean().optional().describe('Take full-page screenshot (for screenshot action)'),
2392
+ interactive: z.boolean().optional().describe('Show interactive elements only (for snapshot action)')
2393
+ }),
2394
+ outputSchema: z.object({
2395
+ success: z.boolean(),
2396
+ title: z.string().optional(),
2397
+ url: z.string().optional(),
2398
+ elements: z.any().optional(),
2399
+ text: z.string().optional(),
2400
+ html: z.string().optional(),
2401
+ result: z.any().optional(),
2402
+ path: z.string().optional(),
2403
+ error: z.string().optional()
2404
+ }),
2405
+ execute: wrapExecute('Browser', async (args: {
2406
+ action: string;
2407
+ url?: string;
2408
+ ref?: string;
2409
+ text?: string;
2410
+ selector?: string;
2411
+ js?: string;
2412
+ fullPage?: boolean;
2413
+ interactive?: boolean;
2414
+ }) => {
2415
+ const { BrowserSession } = await import('./browser.js');
2416
+ const browserConfig = config.browser;
2417
+ const session = new BrowserSession({
2418
+ timeoutMs: browserConfig.timeoutMs,
2419
+ screenshotQuality: browserConfig.screenshotQuality
2420
+ });
2421
+ switch (args.action) {
2422
+ case 'navigate':
2423
+ if (!args.url) return { success: false, error: 'url is required for navigate action' };
2424
+ return session.navigate(args.url);
2425
+ case 'snapshot':
2426
+ return session.snapshot(args.interactive);
2427
+ case 'click':
2428
+ if (!args.ref) return { success: false, error: 'ref is required for click action' };
2429
+ return session.click(args.ref);
2430
+ case 'fill':
2431
+ if (!args.ref || !args.text) return { success: false, error: 'ref and text are required for fill action' };
2432
+ return session.fill(args.ref, args.text);
2433
+ case 'screenshot':
2434
+ return session.screenshot(args.fullPage);
2435
+ case 'extract':
2436
+ return session.extract(args.selector);
2437
+ case 'evaluate':
2438
+ if (!args.js) return { success: false, error: 'js is required for evaluate action' };
2439
+ return session.evaluate(args.js);
2440
+ case 'close':
2441
+ return session.close();
2442
+ default:
2443
+ return { success: false, error: `Unknown action: ${args.action}` };
2444
+ }
2445
+ })
2446
+ });
2447
+
2251
2448
  const tools: Tool[] = [
2252
2449
  readTool,
2253
2450
  writeTool,
@@ -2260,6 +2457,7 @@ export function createTools(
2260
2457
  sendFileTool,
2261
2458
  sendPhotoTool,
2262
2459
  sendVoiceTool,
2460
+ textToSpeechTool,
2263
2461
  sendAudioTool,
2264
2462
  sendLocationTool,
2265
2463
  sendContactTool,
@@ -2279,6 +2477,11 @@ export function createTools(
2279
2477
  listJobsTool,
2280
2478
  cancelJobTool,
2281
2479
  jobUpdateTool,
2480
+ orchestrateTool,
2481
+ workflowStartTool,
2482
+ workflowStatusTool,
2483
+ workflowCancelTool,
2484
+ workflowListTool,
2282
2485
  memoryUpsertTool,
2283
2486
  memoryForgetTool,
2284
2487
  memoryListTool,
@@ -2291,6 +2494,10 @@ export function createTools(
2291
2494
  ...pluginTools
2292
2495
  ];
2293
2496
 
2497
+ if (config.browser.enabled) {
2498
+ tools.push(browserTool as Tool);
2499
+ }
2500
+
2294
2501
  if (enableBash) {
2295
2502
  tools.push(bashTool as Tool);
2296
2503
  tools.push(pythonTool as Tool);
@@ -2303,3 +2510,24 @@ export function createTools(
2303
2510
 
2304
2511
  return tools;
2305
2512
  }
2513
+
2514
+ /**
2515
+ * Discover and merge MCP external tools into the tools array.
2516
+ * Call this after createTools() if MCP is enabled.
2517
+ */
2518
+ export async function discoverMcpTools(
2519
+ config: AgentRuntimeConfig['agent'],
2520
+ wrapExecuteFn: <TInput, TOutput>(name: string, execute: (args: TInput) => Promise<TOutput>) => (args: TInput) => Promise<TOutput>
2521
+ ): Promise<{ tools: Tool[]; cleanup: () => Promise<void> }> {
2522
+ if (!config.mcp.enabled || config.mcp.servers.length === 0) {
2523
+ return { tools: [], cleanup: async () => {} };
2524
+ }
2525
+
2526
+ const { McpToolRegistry } = await import('./mcp-registry.js');
2527
+ const registry = new McpToolRegistry(config.mcp);
2528
+ const mcpTools = await registry.discoverTools(wrapExecuteFn);
2529
+ return {
2530
+ tools: mcpTools,
2531
+ cleanup: () => registry.closeAll()
2532
+ };
2533
+ }
@@ -0,0 +1,61 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { loadAgentConfig } from './agent-config.js';
4
+
5
+ const WORKSPACE_GROUP = '/workspace/group';
6
+ const OUTPUT_DIR = path.join(WORKSPACE_GROUP, 'voice_output');
7
+
8
+ export interface TtsOptions {
9
+ voice?: string;
10
+ language?: string;
11
+ speed?: number;
12
+ }
13
+
14
+ export async function synthesizeSpeech(text: string, options?: TtsOptions): Promise<string> {
15
+ const config = loadAgentConfig();
16
+ const ttsConfig = config.agent.tts;
17
+
18
+ if (!ttsConfig.enabled) {
19
+ throw new Error('TTS is disabled in agent configuration');
20
+ }
21
+
22
+ if (!text || !text.trim()) {
23
+ throw new Error('Text is required for TTS');
24
+ }
25
+
26
+ fs.mkdirSync(OUTPUT_DIR, { recursive: true });
27
+
28
+ const voice = options?.voice || ttsConfig.defaultVoice;
29
+ const lang = options?.language || 'en-US';
30
+ const rate = options?.speed && options.speed !== 1.0
31
+ ? `${options.speed > 1 ? '+' : ''}${Math.round((options.speed - 1) * 100)}%`
32
+ : 'default';
33
+
34
+ const { EdgeTTS } = await import('node-edge-tts');
35
+ const tts = new EdgeTTS({
36
+ voice,
37
+ lang,
38
+ outputFormat: 'audio-24khz-48kbitrate-mono-mp3',
39
+ rate,
40
+ timeout: 15_000,
41
+ });
42
+
43
+ const ts = Date.now();
44
+ const mp3Path = path.join(OUTPUT_DIR, `tts_${ts}.mp3`);
45
+ const oggPath = path.join(OUTPUT_DIR, `tts_${ts}.ogg`);
46
+
47
+ await tts.ttsPromise(text.slice(0, 4096), mp3Path);
48
+
49
+ // Convert MP3 → OGG Opus for Telegram voice notes
50
+ const { execFileSync } = await import('child_process');
51
+ execFileSync('ffmpeg', [
52
+ '-y', '-i', mp3Path,
53
+ '-c:a', 'libopus', '-b:a', '48k',
54
+ oggPath
55
+ ], { timeout: 15_000, stdio: 'pipe' });
56
+
57
+ // Clean up temp MP3
58
+ try { fs.unlinkSync(mp3Path); } catch { /* ignore */ }
59
+
60
+ return oggPath;
61
+ }
@@ -10,6 +10,7 @@
10
10
  "noUnusedParameters": true,
11
11
  "esModuleInterop": true,
12
12
  "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true,
13
14
  "declaration": true,
14
15
  "declarationMap": true,
15
16
  "sourceMap": true
@@ -1 +1 @@
1
- {"version":3,"file":"admin-commands.d.ts","sourceRoot":"","sources":["../src/admin-commands.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AA4DzD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CA6B7F"}
1
+ {"version":3,"file":"admin-commands.d.ts","sourceRoot":"","sources":["../src/admin-commands.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAoEzD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CA6B7F"}
@@ -43,6 +43,18 @@ function normalizeCommand(tokens) {
43
43
  if (first === 'memory') {
44
44
  return { command: 'memory', args: [secondRaw, ...rest].filter(Boolean) };
45
45
  }
46
+ if (first === 'skill') {
47
+ const sub = second || '';
48
+ if (sub === 'install')
49
+ return { command: 'skill-install', args: rest };
50
+ if (sub === 'remove' || sub === 'uninstall')
51
+ return { command: 'skill-remove', args: rest };
52
+ if (sub === 'list' || sub === 'ls')
53
+ return { command: 'skill-list', args: rest };
54
+ if (sub === 'update')
55
+ return { command: 'skill-update', args: rest };
56
+ return { command: 'skill-help', args: [] };
57
+ }
46
58
  if (first === 'groups') {
47
59
  return { command: 'groups', args: [secondRaw, ...rest].filter(Boolean) };
48
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"admin-commands.js","sourceRoot":"","sources":["../src/admin-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"admin-commands.js","sourceRoot":"","sources":["../src/admin-commands.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { AgentContext } from './agent-context.js';
2
+ import type { TaskProfile } from './request-router.js';
2
3
  import type { ContainerOutput } from './container-protocol.js';
3
4
  import type { RegisteredGroup } from './types.js';
4
5
  export type TraceBase = {
@@ -50,6 +51,7 @@ export declare function executeAgentRun(params: {
50
51
  disableResponseValidation?: boolean;
51
52
  responseValidationMaxRetries?: number;
52
53
  disableMemoryExtraction?: boolean;
54
+ profile?: TaskProfile;
53
55
  availableGroups?: Array<{
54
56
  jid: string;
55
57
  name: string;
@@ -77,7 +79,7 @@ export declare function recordAgentTelemetry(params: {
77
79
  traceBase: TraceBase;
78
80
  output: ContainerOutput | null;
79
81
  context: AgentContext;
80
- metricsSource?: 'telegram' | 'scheduler';
82
+ metricsSource?: string;
81
83
  toolAuditSource: 'message' | 'background' | 'scheduler' | 'heartbeat';
82
84
  errorMessage?: string;
83
85
  errorType?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-execution.d.ts","sourceRoot":"","sources":["../src/agent-execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-execution.d.ts","sourceRoot":"","sources":["../src/agent-execution.ts"],"names":[],"mappings":"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"}