@downcity/plugins 1.0.254 → 1.0.280
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/bin/builtin/BuiltinPluginReadmes.d.ts +14 -0
- package/bin/builtin/BuiltinPluginReadmes.d.ts.map +1 -0
- package/bin/builtin/BuiltinPluginReadmes.js +58 -0
- package/bin/builtin/BuiltinPluginReadmes.js.map +1 -0
- package/bin/builtin/BuiltinPluginTypes.d.ts +48 -0
- package/bin/builtin/BuiltinPluginTypes.d.ts.map +1 -0
- package/bin/builtin/BuiltinPluginTypes.js +161 -0
- package/bin/builtin/BuiltinPluginTypes.js.map +1 -0
- package/bin/builtin/PluginSettingsDefinitions.d.ts +9 -0
- package/bin/builtin/PluginSettingsDefinitions.d.ts.map +1 -0
- package/bin/builtin/PluginSettingsDefinitions.js +41 -0
- package/bin/builtin/PluginSettingsDefinitions.js.map +1 -0
- package/bin/builtin/main/PluginSettingsMain.d.ts +6 -0
- package/bin/builtin/main/PluginSettingsMain.d.ts.map +1 -0
- package/bin/builtin/main/PluginSettingsMain.js +65 -0
- package/bin/builtin/main/PluginSettingsMain.js.map +1 -0
- package/bin/builtin/renderer/PluginSettingsRenderer.d.ts +6 -0
- package/bin/builtin/renderer/PluginSettingsRenderer.d.ts.map +1 -0
- package/bin/builtin/renderer/PluginSettingsRenderer.js +76 -0
- package/bin/builtin/renderer/PluginSettingsRenderer.js.map +1 -0
- package/bin/builtin/types/PluginSettings.d.ts +35 -0
- package/bin/builtin/types/PluginSettings.d.ts.map +1 -0
- package/bin/builtin/types/PluginSettings.js +3 -0
- package/bin/builtin/types/PluginSettings.js.map +1 -0
- package/bin/chat/ChatPlugin.d.ts +12 -28
- package/bin/chat/ChatPlugin.d.ts.map +1 -1
- package/bin/chat/ChatPlugin.js +97 -49
- package/bin/chat/ChatPlugin.js.map +1 -1
- package/bin/chat/access/ChatAccessRuntime.js +1 -1
- package/bin/chat/access/ChatAccessRuntime.js.map +1 -1
- package/bin/chat/access/ChatAccessSchema.d.ts +2 -2
- package/bin/chat/access/ChatAccessSchema.d.ts.map +1 -1
- package/bin/chat/access/ChatAccessSchema.js +3 -3
- package/bin/chat/access/ChatAccessSchema.js.map +1 -1
- package/bin/chat/access/ChatAccessService.d.ts +2 -2
- package/bin/chat/access/ChatAccessService.d.ts.map +1 -1
- package/bin/chat/access/ChatAccessService.js +4 -4
- package/bin/chat/access/ChatAccessService.js.map +1 -1
- package/bin/chat/access/ChatAccessStore.d.ts +3 -3
- package/bin/chat/access/ChatAccessStore.d.ts.map +1 -1
- package/bin/chat/access/ChatAccessStore.js +17 -8
- package/bin/chat/access/ChatAccessStore.js.map +1 -1
- package/bin/chat/channels/BaseChatChannel.d.ts +1 -0
- package/bin/chat/channels/BaseChatChannel.d.ts.map +1 -1
- package/bin/chat/channels/BaseChatChannel.js +2 -0
- package/bin/chat/channels/BaseChatChannel.js.map +1 -1
- package/bin/chat/channels/RuntimeChannel.d.ts +4 -4
- package/bin/chat/channels/RuntimeChannel.d.ts.map +1 -1
- package/bin/chat/channels/RuntimeChannel.js +8 -8
- package/bin/chat/channels/RuntimeChannel.js.map +1 -1
- package/bin/chat/channels/feishu/Feishu.js +1 -1
- package/bin/chat/channels/feishu/Feishu.js.map +1 -1
- package/bin/chat/channels/feishu/FeishuPlatformClient.d.ts +1 -0
- package/bin/chat/channels/feishu/FeishuPlatformClient.d.ts.map +1 -1
- package/bin/chat/channels/feishu/FeishuPlatformClient.js +3 -0
- package/bin/chat/channels/feishu/FeishuPlatformClient.js.map +1 -1
- package/bin/chat/channels/feishu/FeishuPlatformLookup.d.ts +2 -0
- package/bin/chat/channels/feishu/FeishuPlatformLookup.d.ts.map +1 -1
- package/bin/chat/channels/feishu/FeishuPlatformLookup.js +1 -1
- package/bin/chat/channels/feishu/FeishuPlatformLookup.js.map +1 -1
- package/bin/chat/channels/qq/QQ.d.ts.map +1 -1
- package/bin/chat/channels/qq/QQ.js +3 -2
- package/bin/chat/channels/qq/QQ.js.map +1 -1
- package/bin/chat/channels/qq/QQEventCapture.d.ts +1 -1
- package/bin/chat/channels/qq/QQEventCapture.d.ts.map +1 -1
- package/bin/chat/channels/qq/QQEventCapture.js +3 -3
- package/bin/chat/channels/qq/QQEventCapture.js.map +1 -1
- package/bin/chat/channels/qq/QQInboundDedupe.d.ts +1 -1
- package/bin/chat/channels/qq/QQInboundDedupe.d.ts.map +1 -1
- package/bin/chat/channels/qq/QQInboundDedupe.js +1 -1
- package/bin/chat/channels/qq/QQInboundDedupe.js.map +1 -1
- package/bin/chat/channels/qq/QQMessageHandler.d.ts +4 -0
- package/bin/chat/channels/qq/QQMessageHandler.d.ts.map +1 -1
- package/bin/chat/channels/qq/QQMessageHandler.js +2 -0
- package/bin/chat/channels/qq/QQMessageHandler.js.map +1 -1
- package/bin/chat/channels/qq/QQSupport.d.ts +4 -0
- package/bin/chat/channels/qq/QQSupport.d.ts.map +1 -1
- package/bin/chat/channels/qq/QQSupport.js +1 -0
- package/bin/chat/channels/qq/QQSupport.js.map +1 -1
- package/bin/chat/channels/qq/VoiceInput.d.ts +3 -0
- package/bin/chat/channels/qq/VoiceInput.d.ts.map +1 -1
- package/bin/chat/channels/qq/VoiceInput.js +1 -1
- package/bin/chat/channels/qq/VoiceInput.js.map +1 -1
- package/bin/chat/channels/telegram/ApiClient.d.ts +3 -1
- package/bin/chat/channels/telegram/ApiClient.d.ts.map +1 -1
- package/bin/chat/channels/telegram/ApiClient.js +4 -2
- package/bin/chat/channels/telegram/ApiClient.js.map +1 -1
- package/bin/chat/channels/telegram/StateStore.d.ts +1 -1
- package/bin/chat/channels/telegram/StateStore.d.ts.map +1 -1
- package/bin/chat/channels/telegram/StateStore.js +2 -2
- package/bin/chat/channels/telegram/StateStore.js.map +1 -1
- package/bin/chat/channels/telegram/TelegramPlatformClient.d.ts.map +1 -1
- package/bin/chat/channels/telegram/TelegramPlatformClient.js +2 -1
- package/bin/chat/channels/telegram/TelegramPlatformClient.js.map +1 -1
- package/bin/chat/main/ChatPluginMain.d.ts +4 -0
- package/bin/chat/main/ChatPluginMain.d.ts.map +1 -0
- package/bin/chat/main/ChatPluginMain.js +137 -0
- package/bin/chat/main/ChatPluginMain.js.map +1 -0
- package/bin/chat/renderer/ChatPluginRenderer.d.ts +4 -0
- package/bin/chat/renderer/ChatPluginRenderer.d.ts.map +1 -0
- package/bin/chat/renderer/ChatPluginRenderer.js +105 -0
- package/bin/chat/renderer/ChatPluginRenderer.js.map +1 -0
- package/bin/chat/runtime/ChannelContextStore.d.ts +2 -2
- package/bin/chat/runtime/ChannelContextStore.js +20 -20
- package/bin/chat/runtime/ChannelContextStore.js.map +1 -1
- package/bin/chat/runtime/ChatActionExecution.js +6 -6
- package/bin/chat/runtime/ChatActionExecution.js.map +1 -1
- package/bin/chat/runtime/ChatChannelConfig.d.ts.map +1 -1
- package/bin/chat/runtime/ChatChannelConfig.js +7 -12
- package/bin/chat/runtime/ChatChannelConfig.js.map +1 -1
- package/bin/chat/runtime/ChatChannelCore.d.ts +3 -3
- package/bin/chat/runtime/ChatChannelCore.d.ts.map +1 -1
- package/bin/chat/runtime/ChatChannelCore.js +5 -5
- package/bin/chat/runtime/ChatChannelCore.js.map +1 -1
- package/bin/chat/runtime/ChatHistoryStore.d.ts +1 -1
- package/bin/chat/runtime/ChatHistoryStore.js +7 -7
- package/bin/chat/runtime/ChatHistoryStore.js.map +1 -1
- package/bin/chat/runtime/ChatMetaStore.d.ts +1 -1
- package/bin/chat/runtime/ChatMetaStore.js +1 -1
- package/bin/chat/runtime/ChatPluginActionRegistry.d.ts +1 -1
- package/bin/chat/runtime/ChatPluginActionRegistry.d.ts.map +1 -1
- package/bin/chat/runtime/ChatPluginActionRegistry.js +9 -9
- package/bin/chat/runtime/ChatPluginActionRegistry.js.map +1 -1
- package/bin/chat/runtime/ChatQueue.d.ts +3 -38
- package/bin/chat/runtime/ChatQueue.d.ts.map +1 -1
- package/bin/chat/runtime/ChatQueue.js +3 -51
- package/bin/chat/runtime/ChatQueue.js.map +1 -1
- package/bin/chat/runtime/ChatQueueStore.d.ts +5 -16
- package/bin/chat/runtime/ChatQueueStore.d.ts.map +1 -1
- package/bin/chat/runtime/ChatQueueStore.js +8 -22
- package/bin/chat/runtime/ChatQueueStore.js.map +1 -1
- package/bin/chat/runtime/ChatQueueWorker.d.ts +1 -1
- package/bin/chat/runtime/ChatQueueWorker.d.ts.map +1 -1
- package/bin/chat/runtime/ChatQueueWorker.js +1 -2
- package/bin/chat/runtime/ChatQueueWorker.js.map +1 -1
- package/bin/chat/runtime/ChatSessionDelete.d.ts +3 -3
- package/bin/chat/runtime/ChatSessionDelete.js +4 -4
- package/bin/chat/runtime/ChatSessionDelete.js.map +1 -1
- package/bin/chat/runtime/ChatStorage.d.ts +7 -7
- package/bin/chat/runtime/ChatStorage.js +24 -24
- package/bin/chat/runtime/ChatStorage.js.map +1 -1
- package/bin/chat/types/ChatAccess.d.ts +2 -2
- package/bin/chat/types/ChatAccess.d.ts.map +1 -1
- package/bin/chat/types/ChatCommand.d.ts +1 -1
- package/bin/chat/types/ChatPluginChannelConfig.d.ts +57 -0
- package/bin/chat/types/ChatPluginChannelConfig.d.ts.map +1 -0
- package/bin/chat/types/ChatPluginChannelConfig.js +3 -0
- package/bin/chat/types/ChatPluginChannelConfig.js.map +1 -0
- package/bin/chat/types/ChatPluginConfig.d.ts +19 -0
- package/bin/chat/types/ChatPluginConfig.d.ts.map +1 -0
- package/bin/chat/types/ChatPluginConfig.js +3 -0
- package/bin/chat/types/ChatPluginConfig.js.map +1 -0
- package/bin/chat/types/ChatPluginOptions.d.ts +4 -4
- package/bin/chat/types/ChatPluginOptions.d.ts.map +1 -1
- package/bin/chat/types/ChatPluginOptions.js +1 -1
- package/bin/chat/types/ChatPluginProfile.d.ts +39 -0
- package/bin/chat/types/ChatPluginProfile.d.ts.map +1 -0
- package/bin/chat/types/ChatPluginProfile.js +3 -0
- package/bin/chat/types/ChatPluginProfile.js.map +1 -0
- package/bin/chat/types/ChatPluginRenderer.d.ts +17 -0
- package/bin/chat/types/ChatPluginRenderer.d.ts.map +1 -0
- package/bin/chat/types/ChatPluginRenderer.js +3 -0
- package/bin/chat/types/ChatPluginRenderer.js.map +1 -0
- package/bin/chat/types/ChatRuntime.d.ts +11 -0
- package/bin/chat/types/ChatRuntime.d.ts.map +1 -1
- package/bin/chat/types/ChatRuntimeAccount.d.ts +3 -3
- package/bin/chat/types/ChatRuntimeAccount.d.ts.map +1 -1
- package/bin/chat/types/ChatRuntimeAccount.js +2 -2
- package/bin/chat/types/ChatStorage.d.ts +2 -2
- package/bin/chat/types/ChatStorage.d.ts.map +1 -1
- package/bin/chat.d.ts +3 -4
- package/bin/chat.d.ts.map +1 -1
- package/bin/chat.js +1 -2
- package/bin/chat.js.map +1 -1
- package/bin/contact/Action.js +5 -5
- package/bin/contact/Action.js.map +1 -1
- package/bin/contact/ContactPlugin.js +15 -15
- package/bin/contact/ContactPlugin.js.map +1 -1
- package/bin/contact/runtime/ChatRuntime.js +3 -3
- package/bin/contact/runtime/ChatRuntime.js.map +1 -1
- package/bin/contact/runtime/ContactStore.d.ts +8 -8
- package/bin/contact/runtime/ContactStore.d.ts.map +1 -1
- package/bin/contact/runtime/ContactStore.js +20 -20
- package/bin/contact/runtime/ContactStore.js.map +1 -1
- package/bin/contact/runtime/EndpointNotice.js +2 -2
- package/bin/contact/runtime/EndpointNotice.js.map +1 -1
- package/bin/contact/runtime/InboxStore.d.ts +6 -6
- package/bin/contact/runtime/InboxStore.d.ts.map +1 -1
- package/bin/contact/runtime/InboxStore.js +16 -16
- package/bin/contact/runtime/InboxStore.js.map +1 -1
- package/bin/contact/runtime/LinkApproval.js +14 -14
- package/bin/contact/runtime/LinkApproval.js.map +1 -1
- package/bin/contact/runtime/LinkStore.d.ts +2 -2
- package/bin/contact/runtime/LinkStore.d.ts.map +1 -1
- package/bin/contact/runtime/LinkStore.js +5 -5
- package/bin/contact/runtime/LinkStore.js.map +1 -1
- package/bin/contact/runtime/Paths.d.ts +15 -15
- package/bin/contact/runtime/Paths.d.ts.map +1 -1
- package/bin/contact/runtime/Paths.js +29 -29
- package/bin/contact/runtime/Paths.js.map +1 -1
- package/bin/contact/runtime/ShareBundle.d.ts +1 -1
- package/bin/contact/runtime/ShareBundle.d.ts.map +1 -1
- package/bin/contact/runtime/ShareBundle.js +4 -4
- package/bin/contact/runtime/ShareBundle.js.map +1 -1
- package/bin/contact/types/ContactApproval.d.ts +2 -2
- package/bin/contact/types/ContactApproval.d.ts.map +1 -1
- package/bin/image/ImagePlugin.d.ts +1 -4
- package/bin/image/ImagePlugin.d.ts.map +1 -1
- package/bin/image/ImagePlugin.js +26 -34
- package/bin/image/ImagePlugin.js.map +1 -1
- package/bin/image/runtime/ImageResultStorage.d.ts +2 -2
- package/bin/image/runtime/ImageResultStorage.d.ts.map +1 -1
- package/bin/image/runtime/ImageResultStorage.js +15 -38
- package/bin/image/runtime/ImageResultStorage.js.map +1 -1
- package/bin/image/types/ImagePlugin.d.ts +23 -16
- package/bin/image/types/ImagePlugin.d.ts.map +1 -1
- package/bin/image/types/ImagePlugin.js +1 -1
- package/bin/image.d.ts +1 -1
- package/bin/image.d.ts.map +1 -1
- package/bin/index.d.ts +2 -0
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +1 -0
- package/bin/index.js.map +1 -1
- package/bin/memory/MemoryPlugin.d.ts +1 -1
- package/bin/memory/MemoryPlugin.d.ts.map +1 -1
- package/bin/memory/MemoryPlugin.js +17 -7
- package/bin/memory/MemoryPlugin.js.map +1 -1
- package/bin/memory/types/Memory.d.ts +10 -4
- package/bin/memory/types/Memory.d.ts.map +1 -1
- package/bin/memory.d.ts +1 -1
- package/bin/memory.d.ts.map +1 -1
- package/bin/renderers.d.ts +5 -0
- package/bin/renderers.d.ts.map +1 -0
- package/bin/renderers.js +12 -0
- package/bin/renderers.js.map +1 -0
- package/bin/sound/Plugin.d.ts +2 -5
- package/bin/sound/Plugin.d.ts.map +1 -1
- package/bin/sound/Plugin.js +27 -31
- package/bin/sound/Plugin.js.map +1 -1
- package/bin/sound/types/SoundPlugin.d.ts +22 -15
- package/bin/sound/types/SoundPlugin.d.ts.map +1 -1
- package/bin/sound/types/SoundPlugin.js +2 -2
- package/bin/sound.d.ts +1 -1
- package/bin/sound.d.ts.map +1 -1
- package/bin/task/Action.d.ts +6 -6
- package/bin/task/Action.d.ts.map +1 -1
- package/bin/task/Action.js +21 -21
- package/bin/task/Action.js.map +1 -1
- package/bin/task/PROMPT.d.ts +1 -1
- package/bin/task/PROMPT.d.ts.map +1 -1
- package/bin/task/PROMPT.js +1 -1
- package/bin/task/PROMPT.js.map +1 -1
- package/bin/task/Scheduler.js +8 -8
- package/bin/task/Scheduler.js.map +1 -1
- package/bin/task/TaskPlugin.d.ts +7 -14
- package/bin/task/TaskPlugin.d.ts.map +1 -1
- package/bin/task/TaskPlugin.js +54 -43
- package/bin/task/TaskPlugin.js.map +1 -1
- package/bin/task/runtime/Model.d.ts +1 -5
- package/bin/task/runtime/Model.d.ts.map +1 -1
- package/bin/task/runtime/Model.js +2 -13
- package/bin/task/runtime/Model.js.map +1 -1
- package/bin/task/runtime/Paths.d.ts +7 -7
- package/bin/task/runtime/Paths.d.ts.map +1 -1
- package/bin/task/runtime/Paths.js +11 -11
- package/bin/task/runtime/Paths.js.map +1 -1
- package/bin/task/runtime/Runner.d.ts +1 -1
- package/bin/task/runtime/Runner.d.ts.map +1 -1
- package/bin/task/runtime/Runner.js +4 -5
- package/bin/task/runtime/Runner.js.map +1 -1
- package/bin/task/runtime/Store.d.ts +9 -9
- package/bin/task/runtime/Store.d.ts.map +1 -1
- package/bin/task/runtime/Store.js +17 -17
- package/bin/task/runtime/Store.js.map +1 -1
- package/bin/task/runtime/TaskActionExecution.js +6 -6
- package/bin/task/runtime/TaskActionExecution.js.map +1 -1
- package/bin/task/runtime/TaskPluginActionRegistry.js +1 -1
- package/bin/task/runtime/TaskPluginActionRegistry.js.map +1 -1
- package/bin/task/runtime/TaskRunnerRound.d.ts +0 -1
- package/bin/task/runtime/TaskRunnerRound.d.ts.map +1 -1
- package/bin/task/runtime/TaskRunnerRound.js +8 -3
- package/bin/task/runtime/TaskRunnerRound.js.map +1 -1
- package/bin/task/runtime/TaskRunnerScript.d.ts +0 -4
- package/bin/task/runtime/TaskRunnerScript.d.ts.map +1 -1
- package/bin/task/runtime/TaskRunnerScript.js +0 -1
- package/bin/task/runtime/TaskRunnerScript.js.map +1 -1
- package/bin/task/runtime/TaskRunnerSession.d.ts +2 -3
- package/bin/task/runtime/TaskRunnerSession.d.ts.map +1 -1
- package/bin/task/runtime/TaskRunnerSession.js +2 -4
- package/bin/task/runtime/TaskRunnerSession.js.map +1 -1
- package/bin/task/types/TaskWorkspaceRuntime.d.ts +10 -0
- package/bin/task/types/TaskWorkspaceRuntime.d.ts.map +1 -0
- package/bin/task/types/TaskWorkspaceRuntime.js +3 -0
- package/bin/task/types/TaskWorkspaceRuntime.js.map +1 -0
- package/bin/web/Plugin.d.ts +2 -6
- package/bin/web/Plugin.d.ts.map +1 -1
- package/bin/web/Plugin.js +21 -17
- package/bin/web/Plugin.js.map +1 -1
- package/bin/web/providers/PlaywrightBrowserProvider.d.ts.map +1 -1
- package/bin/web/providers/PlaywrightBrowserProvider.js +59 -14
- package/bin/web/providers/PlaywrightBrowserProvider.js.map +1 -1
- package/bin/web/types/WebPlugin.d.ts +15 -9
- package/bin/web/types/WebPlugin.d.ts.map +1 -1
- package/bin/web.d.ts +1 -1
- package/bin/web.d.ts.map +1 -1
- package/bin/workboard/runtime/Collector.js +1 -1
- package/bin/workboard/runtime/Collector.js.map +1 -1
- package/package.json +29 -20
- package/scripts/chat-access.test.mjs +3 -2
- package/scripts/chat-channel-config.test.mjs +3 -3
- package/scripts/chat-storage.test.mjs +10 -14
- package/scripts/memory-plugin.test.mjs +9 -32
- package/scripts/playwright-browser-provider.test.mjs +260 -0
- package/scripts/plugin-main.test.mjs +101 -0
- package/scripts/plugin-subpaths.test.mjs +28 -0
- package/scripts/sound-plugin.test.mjs +21 -9
- package/scripts/unrestricted-sandbox-approval.test.mjs +1 -1
- package/scripts/web-plugin.test.mjs +43 -186
- package/src/builtin/BuiltinPluginReadmes.ts +58 -0
- package/src/builtin/BuiltinPluginTypes.ts +260 -0
- package/src/builtin/PluginSettingsDefinitions.ts +45 -0
- package/src/builtin/main/PluginSettingsMain.ts +75 -0
- package/src/builtin/renderer/PluginSettingsRenderer.tsx +110 -0
- package/src/builtin/types/PluginSettings.ts +46 -0
- package/src/chat/ChatPlugin.ts +99 -51
- package/src/chat/access/ChatAccessRuntime.ts +1 -1
- package/src/chat/access/ChatAccessSchema.ts +5 -5
- package/src/chat/access/ChatAccessService.ts +4 -4
- package/src/chat/access/ChatAccessStore.ts +17 -9
- package/src/chat/channels/BaseChatChannel.ts +2 -0
- package/src/chat/channels/RuntimeChannel.ts +9 -9
- package/src/chat/channels/feishu/Feishu.ts +1 -1
- package/src/chat/channels/feishu/FeishuPlatformClient.ts +3 -0
- package/src/chat/channels/feishu/FeishuPlatformLookup.ts +3 -1
- package/src/chat/channels/qq/QQ.ts +3 -2
- package/src/chat/channels/qq/QQEventCapture.ts +3 -3
- package/src/chat/channels/qq/QQInboundDedupe.ts +2 -3
- package/src/chat/channels/qq/QQMessageHandler.ts +6 -0
- package/src/chat/channels/qq/QQSupport.ts +5 -0
- package/src/chat/channels/qq/VoiceInput.ts +5 -1
- package/src/chat/channels/telegram/ApiClient.ts +10 -3
- package/src/chat/channels/telegram/StateStore.ts +2 -2
- package/src/chat/channels/telegram/TelegramPlatformClient.ts +2 -1
- package/src/chat/main/ChatPluginMain.ts +163 -0
- package/src/chat/renderer/ChatPluginRenderer.tsx +149 -0
- package/src/chat/runtime/ChannelContextStore.ts +20 -20
- package/src/chat/runtime/ChatActionExecution.ts +6 -6
- package/src/chat/runtime/ChatChannelConfig.ts +7 -14
- package/src/chat/runtime/ChatChannelCore.ts +9 -9
- package/src/chat/runtime/ChatHistoryStore.ts +7 -7
- package/src/chat/runtime/ChatMetaStore.ts +1 -1
- package/src/chat/runtime/ChatPluginActionRegistry.ts +10 -10
- package/src/chat/runtime/ChatQueue.ts +2 -69
- package/src/chat/runtime/ChatQueueStore.ts +10 -26
- package/src/chat/runtime/ChatQueueWorker.ts +2 -5
- package/src/chat/runtime/ChatSessionDelete.ts +4 -4
- package/src/chat/runtime/ChatStorage.ts +24 -24
- package/src/chat/types/ChatAccess.ts +2 -2
- package/src/chat/types/ChatCommand.ts +1 -1
- package/src/chat/types/ChatPluginChannelConfig.ts +63 -0
- package/src/chat/types/ChatPluginConfig.ts +21 -0
- package/src/chat/types/ChatPluginOptions.ts +4 -4
- package/src/chat/types/ChatPluginProfile.ts +52 -0
- package/src/chat/types/ChatPluginRenderer.ts +25 -0
- package/src/chat/types/ChatRuntime.ts +14 -0
- package/src/chat/types/ChatRuntimeAccount.ts +3 -3
- package/src/chat/types/ChatStorage.ts +2 -2
- package/src/chat.ts +6 -14
- package/src/contact/Action.ts +5 -5
- package/src/contact/ContactPlugin.ts +15 -15
- package/src/contact/runtime/ChatRuntime.ts +3 -3
- package/src/contact/runtime/ContactStore.ts +20 -20
- package/src/contact/runtime/EndpointNotice.ts +2 -2
- package/src/contact/runtime/InboxStore.ts +16 -16
- package/src/contact/runtime/LinkApproval.ts +16 -16
- package/src/contact/runtime/LinkStore.ts +5 -5
- package/src/contact/runtime/Paths.ts +29 -29
- package/src/contact/runtime/ShareBundle.ts +5 -5
- package/src/contact/types/ContactApproval.ts +2 -2
- package/src/image/ImagePlugin.ts +30 -33
- package/src/image/runtime/ImageResultStorage.ts +36 -62
- package/src/image/types/ImagePlugin.ts +25 -19
- package/src/image.ts +2 -0
- package/src/index.ts +8 -0
- package/src/memory/MemoryPlugin.ts +17 -5
- package/src/memory/types/Memory.ts +11 -4
- package/src/memory.ts +1 -0
- package/src/renderers.ts +18 -0
- package/src/sound/Plugin.ts +34 -33
- package/src/sound/types/SoundPlugin.ts +24 -19
- package/src/sound.ts +2 -0
- package/src/task/Action.ts +27 -27
- package/src/task/PROMPT.ts +1 -1
- package/src/task/PROMPT.ts.txt +5 -6
- package/src/task/Scheduler.ts +8 -8
- package/src/task/TaskPlugin.ts +55 -46
- package/src/task/runtime/Model.ts +3 -13
- package/src/task/runtime/Paths.ts +11 -11
- package/src/task/runtime/Runner.ts +5 -6
- package/src/task/runtime/Store.ts +22 -22
- package/src/task/runtime/TaskActionExecution.ts +6 -6
- package/src/task/runtime/TaskPluginActionRegistry.ts +1 -1
- package/src/task/runtime/TaskRunnerRound.ts +13 -4
- package/src/task/runtime/TaskRunnerScript.ts +0 -5
- package/src/task/runtime/TaskRunnerSession.ts +10 -8
- package/src/task/types/TaskWorkspaceRuntime.ts +12 -0
- package/src/web/Plugin.ts +23 -22
- package/src/web/providers/PlaywrightBrowserProvider.ts +93 -17
- package/src/web/types/WebPlugin.ts +16 -13
- package/src/web.ts +1 -0
- package/src/workboard/runtime/Collector.ts +1 -1
- package/tsconfig.json +4 -1
- package/LICENSE +0 -183
- package/bin/chat/Index.d.ts +0 -15
- package/bin/chat/Index.d.ts.map +0 -1
- package/bin/chat/Index.js +0 -11
- package/bin/chat/Index.js.map +0 -1
- package/bin/chat/config/ChatPluginConfig.d.ts +0 -67
- package/bin/chat/config/ChatPluginConfig.d.ts.map +0 -1
- package/bin/chat/config/ChatPluginConfig.js +0 -237
- package/bin/chat/config/ChatPluginConfig.js.map +0 -1
- package/bin/chat/types/ChatPluginResource.d.ts +0 -68
- package/bin/chat/types/ChatPluginResource.d.ts.map +0 -1
- package/bin/chat/types/ChatPluginResource.js +0 -10
- package/bin/chat/types/ChatPluginResource.js.map +0 -1
- package/bin/contact/Index.d.ts +0 -8
- package/bin/contact/Index.d.ts.map +0 -1
- package/bin/contact/Index.js +0 -8
- package/bin/contact/Index.js.map +0 -1
- package/bin/memory/Index.d.ts +0 -11
- package/bin/memory/Index.d.ts.map +0 -1
- package/bin/memory/Index.js +0 -11
- package/bin/memory/Index.js.map +0 -1
- package/bin/skill/Command.d.ts +0 -29
- package/bin/skill/Command.d.ts.map +0 -1
- package/bin/skill/Command.js +0 -35
- package/bin/skill/Command.js.map +0 -1
- package/bin/task/Index.d.ts +0 -9
- package/bin/task/Index.d.ts.map +0 -1
- package/bin/task/Index.js +0 -9
- package/bin/task/Index.js.map +0 -1
- package/src/chat/Index.ts +0 -36
- package/src/chat/config/ChatPluginConfig.ts +0 -266
- package/src/chat/types/ChatPluginResource.ts +0 -95
- package/src/contact/Index.ts +0 -8
- package/src/memory/Index.ts +0 -14
- package/src/skill/Command.ts +0 -58
- package/src/task/Index.ts +0 -8
package/src/sound/Plugin.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 对 Agent 暴露 `models`、`asr`、`tts` 三个 action。
|
|
6
|
-
* - 模型目录与真实 ASR/TTS
|
|
6
|
+
* - 模型目录与真实 ASR/TTS 能力从运行时 Context 的 City 环境读取。
|
|
7
7
|
* - 本地音频只负责读取并转换为 data URL,不加载或运行任何本地语音模型。
|
|
8
|
-
* - TTS 返回已经落盘的本地音频
|
|
8
|
+
* - TTS 返回已经落盘的本地音频 Session Parts,并由 Action 声明 Assistant Message。
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import fs from "node:fs/promises";
|
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
} from "@/chat/types/ChatPlugin.js";
|
|
21
21
|
import type {
|
|
22
22
|
SoundPluginAsrInput,
|
|
23
|
+
SoundAiService,
|
|
23
24
|
SoundPluginAsrResult,
|
|
24
25
|
SoundPluginAsrSegment,
|
|
25
26
|
SoundPluginCapability,
|
|
@@ -36,6 +37,17 @@ const DEFAULT_SOUND_PLUGIN_DESCRIPTION =
|
|
|
36
37
|
"Transcribe audio and synthesize speech through FED-provided models.";
|
|
37
38
|
const DEFAULT_AUDIO_MEDIA_TYPE = "audio/mpeg";
|
|
38
39
|
|
|
40
|
+
/** 从 City 注入的 Embassy 获取语音 AI 服务。 */
|
|
41
|
+
function require_sound_ai(context: PluginContext): SoundAiService {
|
|
42
|
+
const service = context.embassy?.user.ai;
|
|
43
|
+
if (!service) throw new Error("SoundPlugin requires a City Embassy user AI service");
|
|
44
|
+
return {
|
|
45
|
+
catalog: async () => await service.catalog(),
|
|
46
|
+
asr: async (input) => await service.asr(input as never),
|
|
47
|
+
tts: async (input) => await service.tts(input as never),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
const AUDIO_MEDIA_TYPES: Record<string, string> = {
|
|
40
52
|
".aac": "audio/aac",
|
|
41
53
|
".flac": "audio/flac",
|
|
@@ -356,21 +368,21 @@ function normalize_asr_result(result: SoundPluginAsrResult): SoundPluginAsrResul
|
|
|
356
368
|
}
|
|
357
369
|
|
|
358
370
|
/**
|
|
359
|
-
* 校验 TTS 返回的
|
|
371
|
+
* 校验 TTS 返回的 Downcity Session 消息。
|
|
360
372
|
*/
|
|
361
373
|
function normalize_tts_result(result: SoundPluginTtsResult): SoundPluginTtsResult {
|
|
362
374
|
const record = to_record(result);
|
|
363
375
|
if (!record || !Array.isArray(record.parts)) {
|
|
364
|
-
throw new TypeError("SoundPlugin tts function must return
|
|
376
|
+
throw new TypeError("SoundPlugin tts function must return a Downcity Session message");
|
|
365
377
|
}
|
|
366
378
|
const has_audio_file = record.parts.some((part) => {
|
|
367
379
|
const part_record = to_record(part);
|
|
368
380
|
return part_record?.type === "file"
|
|
369
|
-
&& typeof part_record.
|
|
370
|
-
&& part_record.
|
|
381
|
+
&& typeof part_record.media_type === "string"
|
|
382
|
+
&& part_record.media_type.startsWith("audio/");
|
|
371
383
|
});
|
|
372
384
|
if (!has_audio_file) {
|
|
373
|
-
throw new TypeError("SoundPlugin tts
|
|
385
|
+
throw new TypeError("SoundPlugin tts Session message must contain an audio file part");
|
|
374
386
|
}
|
|
375
387
|
for (const part of record.parts) {
|
|
376
388
|
const part_record = to_record(part);
|
|
@@ -433,25 +445,15 @@ export class SoundPlugin extends BasePlugin {
|
|
|
433
445
|
/** Plugin 用途说明。 */
|
|
434
446
|
readonly description: string;
|
|
435
447
|
|
|
436
|
-
private readonly asr_handler: SoundPluginOptions["asr"];
|
|
437
|
-
private readonly tts_handler: SoundPluginOptions["tts"];
|
|
438
|
-
private readonly list_models?: SoundPluginOptions["list_models"];
|
|
439
448
|
private readonly default_asr_model?: string;
|
|
440
449
|
private readonly default_tts_model?: string;
|
|
441
450
|
private readonly auto_asr: boolean;
|
|
442
451
|
private readonly language?: string;
|
|
443
452
|
private readonly voice?: string;
|
|
444
453
|
private readonly format?: string;
|
|
445
|
-
|
|
446
454
|
constructor(options: SoundPluginOptions) {
|
|
447
455
|
super();
|
|
448
456
|
const name = normalize_optional_string(options.name) ?? DEFAULT_SOUND_PLUGIN_NAME;
|
|
449
|
-
if (typeof options.asr !== "function") {
|
|
450
|
-
throw new TypeError("SoundPlugin requires an asr function");
|
|
451
|
-
}
|
|
452
|
-
if (typeof options.tts !== "function") {
|
|
453
|
-
throw new TypeError("SoundPlugin requires a tts function");
|
|
454
|
-
}
|
|
455
457
|
const default_asr_model = normalize_optional_string(options.default_asr_model);
|
|
456
458
|
if (options.auto_asr === true && !default_asr_model) {
|
|
457
459
|
throw new TypeError("SoundPlugin auto_asr requires default_asr_model");
|
|
@@ -460,9 +462,6 @@ export class SoundPlugin extends BasePlugin {
|
|
|
460
462
|
this.title = normalize_optional_string(options.title) ?? DEFAULT_SOUND_PLUGIN_TITLE;
|
|
461
463
|
this.description = normalize_optional_string(options.description)
|
|
462
464
|
?? DEFAULT_SOUND_PLUGIN_DESCRIPTION;
|
|
463
|
-
this.asr_handler = options.asr;
|
|
464
|
-
this.tts_handler = options.tts;
|
|
465
|
-
this.list_models = options.list_models;
|
|
466
465
|
this.default_asr_model = default_asr_model;
|
|
467
466
|
this.default_tts_model = normalize_optional_string(options.default_tts_model);
|
|
468
467
|
this.auto_asr = options.auto_asr === true;
|
|
@@ -498,7 +497,7 @@ export class SoundPlugin extends BasePlugin {
|
|
|
498
497
|
"## Results",
|
|
499
498
|
"",
|
|
500
499
|
"ASR returns transcript text and may include timed segments, language, and duration.",
|
|
501
|
-
"TTS returns
|
|
500
|
+
"TTS returns a Downcity Session message whose audio file part already points to a local file, and that part is attached to the assistant response.",
|
|
502
501
|
"Do not invent a transcript or audio result when a FED call fails.",
|
|
503
502
|
"",
|
|
504
503
|
`When unsure, use \`plugin_read { plugin: \"${this.name}\", action: \"...\" }\` to inspect the complete schema.`,
|
|
@@ -518,22 +517,24 @@ export class SoundPlugin extends BasePlugin {
|
|
|
518
517
|
...input,
|
|
519
518
|
model,
|
|
520
519
|
});
|
|
521
|
-
return normalize_asr_result(
|
|
520
|
+
return normalize_asr_result(
|
|
521
|
+
await require_sound_ai(context).asr(resolved_input as unknown as JsonObject) as unknown as SoundPluginAsrResult,
|
|
522
|
+
);
|
|
522
523
|
}
|
|
523
524
|
|
|
524
525
|
/**
|
|
525
526
|
* 执行一次 TTS 合成。
|
|
526
527
|
*/
|
|
527
|
-
private async synthesize(input: SoundPluginTtsInput): Promise<SoundPluginTtsResult> {
|
|
528
|
+
private async synthesize(context: PluginContext, input: SoundPluginTtsInput): Promise<SoundPluginTtsResult> {
|
|
528
529
|
const model = resolve_model_id("tts", input.model, this.default_tts_model);
|
|
529
|
-
const result = await
|
|
530
|
+
const result = await require_sound_ai(context).tts({
|
|
530
531
|
...(this.language ? { language: this.language } : {}),
|
|
531
532
|
...(this.voice ? { voice: this.voice } : {}),
|
|
532
533
|
...(this.format ? { format: this.format } : {}),
|
|
533
534
|
...input,
|
|
534
535
|
model,
|
|
535
536
|
});
|
|
536
|
-
return normalize_tts_result(result);
|
|
537
|
+
return normalize_tts_result(result as unknown as SoundPluginTtsResult);
|
|
537
538
|
}
|
|
538
539
|
|
|
539
540
|
/**
|
|
@@ -609,13 +610,13 @@ export class SoundPlugin extends BasePlugin {
|
|
|
609
610
|
{ title: "ASR models", payload: { capability: "asr" } },
|
|
610
611
|
{ title: "TTS models", payload: { capability: "tts" } },
|
|
611
612
|
],
|
|
612
|
-
execute: async ({ input }: { input: JsonValue }) => {
|
|
613
|
+
execute: async ({ context, input }: { context: PluginContext; input: JsonValue }) => {
|
|
613
614
|
try {
|
|
614
|
-
if (!this.list_models) {
|
|
615
|
-
throw new TypeError("SoundPlugin list_models is not configured");
|
|
616
|
-
}
|
|
617
615
|
const capability = normalize_models_capability(input);
|
|
618
|
-
const result = normalize_sound_models(
|
|
616
|
+
const result = normalize_sound_models(
|
|
617
|
+
await require_sound_ai(context).catalog().then((catalog) => catalog.all()) as unknown as SoundPluginModel[],
|
|
618
|
+
capability,
|
|
619
|
+
);
|
|
619
620
|
return {
|
|
620
621
|
success: true,
|
|
621
622
|
data: result as unknown as JsonObject,
|
|
@@ -666,7 +667,7 @@ export class SoundPlugin extends BasePlugin {
|
|
|
666
667
|
}),
|
|
667
668
|
tts: create_action({
|
|
668
669
|
description:
|
|
669
|
-
"Synthesize speech with a FED TTS model and return
|
|
670
|
+
"Synthesize speech with a FED TTS model and return a Downcity Session message containing audio.",
|
|
670
671
|
input_schema: {
|
|
671
672
|
zod: SOUND_TTS_INPUT_SCHEMA,
|
|
672
673
|
json_schema: {
|
|
@@ -691,9 +692,9 @@ export class SoundPlugin extends BasePlugin {
|
|
|
691
692
|
payload: { model: "tts-model-id", text: "Welcome back", voice: "alloy", format: "mp3" },
|
|
692
693
|
},
|
|
693
694
|
],
|
|
694
|
-
execute: async ({ input }: { input: JsonValue }) => {
|
|
695
|
+
execute: async ({ context, input }: { context: PluginContext; input: JsonValue }) => {
|
|
695
696
|
try {
|
|
696
|
-
const result = await this.synthesize(normalize_tts_payload(input));
|
|
697
|
+
const result = await this.synthesize(context, normalize_tts_payload(input));
|
|
697
698
|
return {
|
|
698
699
|
success: true,
|
|
699
700
|
message: "speech synthesized",
|
|
@@ -3,12 +3,23 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - SoundPlugin 统一承载 ASR 与 TTS,不绑定本地模型、Python 或具体 provider。
|
|
6
|
-
* - ASR
|
|
7
|
-
* - TTS 结果直接使用
|
|
6
|
+
* - ASR 结果只保留跨进程可序列化的核心字段。
|
|
7
|
+
* - TTS 结果直接使用 Downcity Session 消息,由 Agent 统一处理音频 file part。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
11
|
-
|
|
10
|
+
import type { ActionResultMessage, JsonObject, JsonValue } from "@downcity/agent";
|
|
11
|
+
|
|
12
|
+
/** SoundPlugin 使用的最小语音 AI 服务协议。 */
|
|
13
|
+
export interface SoundAiService {
|
|
14
|
+
/** 读取当前可用模型目录。 */
|
|
15
|
+
catalog(): Promise<{ all(): readonly unknown[] }>;
|
|
16
|
+
|
|
17
|
+
/** 执行语音识别。 */
|
|
18
|
+
asr(input: JsonObject): Promise<unknown>;
|
|
19
|
+
|
|
20
|
+
/** 执行语音合成。 */
|
|
21
|
+
tts(input: JsonObject): Promise<unknown>;
|
|
22
|
+
}
|
|
12
23
|
|
|
13
24
|
/**
|
|
14
25
|
* SoundPlugin 支持的语音能力。
|
|
@@ -44,7 +55,7 @@ export interface SoundPluginModelsResult {
|
|
|
44
55
|
/**
|
|
45
56
|
* ASR 转写分段。
|
|
46
57
|
*
|
|
47
|
-
*
|
|
58
|
+
* 字段命名遵循 Downcity ASR 分段协议。
|
|
48
59
|
*/
|
|
49
60
|
export interface SoundPluginAsrSegment {
|
|
50
61
|
/** 当前时间片段识别得到的文本。 */
|
|
@@ -83,7 +94,7 @@ export interface SoundPluginAsrInput {
|
|
|
83
94
|
* ASR 输出。
|
|
84
95
|
*
|
|
85
96
|
* 说明(中文)
|
|
86
|
-
* -
|
|
97
|
+
* - 只保留适合 JSON 传输的核心字段。
|
|
87
98
|
* - warnings、responses 与 providerMetadata 属于运行期诊断信息,不进入 plugin action 协议。
|
|
88
99
|
*/
|
|
89
100
|
export interface SoundPluginAsrResult {
|
|
@@ -124,14 +135,14 @@ export interface SoundPluginTtsInput {
|
|
|
124
135
|
/**
|
|
125
136
|
* TTS 输出。
|
|
126
137
|
*
|
|
127
|
-
* 音频通过
|
|
138
|
+
* 音频通过 Downcity Session 消息的 file part 返回。
|
|
128
139
|
*/
|
|
129
|
-
export type SoundPluginTtsResult =
|
|
140
|
+
export type SoundPluginTtsResult = ActionResultMessage;
|
|
130
141
|
|
|
131
142
|
/**
|
|
132
143
|
* SoundPlugin 构造参数。
|
|
133
144
|
*/
|
|
134
|
-
export interface
|
|
145
|
+
export interface SoundPluginProfile {
|
|
135
146
|
/** Plugin 稳定名称,默认 `sound`。 */
|
|
136
147
|
name?: string;
|
|
137
148
|
/** Plugin 展示标题,默认 `Sound`。 */
|
|
@@ -150,14 +161,8 @@ export interface SoundPluginOptions {
|
|
|
150
161
|
voice?: string;
|
|
151
162
|
/** TTS 默认输出格式。 */
|
|
152
163
|
format?: string;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/** 调用 FED TTS action 的函数,通常传入 `(input) => city.ai.tts(input)`。 */
|
|
158
|
-
tts: (
|
|
159
|
-
input: SoundPluginTtsInput,
|
|
160
|
-
) => Promise<SoundPluginTtsResult> | SoundPluginTtsResult;
|
|
161
|
-
/** 列出 FED 中支持 ASR 或 TTS 的模型。 */
|
|
162
|
-
list_models?: () => Promise<SoundPluginModel[]> | SoundPluginModel[];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** SoundPlugin 构造参数。 */
|
|
167
|
+
export interface SoundPluginOptions extends SoundPluginProfile {
|
|
163
168
|
}
|
package/src/sound.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
export { SoundPlugin } from "./sound/Plugin.js";
|
|
8
8
|
export type {
|
|
9
|
+
SoundAiService,
|
|
9
10
|
SoundPluginAsrInput,
|
|
10
11
|
SoundPluginAsrResult,
|
|
11
12
|
SoundPluginAsrSegment,
|
|
@@ -13,6 +14,7 @@ export type {
|
|
|
13
14
|
SoundPluginModel,
|
|
14
15
|
SoundPluginModelsResult,
|
|
15
16
|
SoundPluginOptions,
|
|
17
|
+
SoundPluginProfile,
|
|
16
18
|
SoundPluginTtsInput,
|
|
17
19
|
SoundPluginTtsResult,
|
|
18
20
|
} from "./sound/types/SoundPlugin.js";
|
package/src/task/Action.ts
CHANGED
|
@@ -58,7 +58,7 @@ function buildDefaultTaskBody(): string {
|
|
|
58
58
|
"# 任务目标",
|
|
59
59
|
"",
|
|
60
60
|
"- 明确这次任务最终要交付什么结果,最终回复会由系统自动发送到任务绑定的 chat。",
|
|
61
|
-
"-
|
|
61
|
+
"- 如果需要向用户交付额外文件,请写入明确的项目路径。",
|
|
62
62
|
"",
|
|
63
63
|
"# 背景与输入",
|
|
64
64
|
"",
|
|
@@ -69,7 +69,7 @@ function buildDefaultTaskBody(): string {
|
|
|
69
69
|
"",
|
|
70
70
|
"1. 先理解任务目标与完成标准。",
|
|
71
71
|
"2. 按需要收集信息、执行分析或运行命令。",
|
|
72
|
-
"3.
|
|
72
|
+
"3. 需要文件交付时,把产物写入明确的项目路径。",
|
|
73
73
|
"4. 整理出面向用户可直接阅读的最终结果。",
|
|
74
74
|
"",
|
|
75
75
|
"# 输出要求",
|
|
@@ -87,7 +87,7 @@ function buildDefaultTaskBody(): string {
|
|
|
87
87
|
"# 注意事项",
|
|
88
88
|
"",
|
|
89
89
|
"- 当前是独立 task 上下文,不要假设仍处在原始聊天回合里。",
|
|
90
|
-
"-
|
|
90
|
+
"- 任务运行记录由系统保存在当前 Agent 的私有目录;需要交付给用户的文件应明确写入项目目录。",
|
|
91
91
|
"- 如果任务明确要求跨会话、跨平台或发送额外通知,再显式调用 chat plugin 的发送 action。",
|
|
92
92
|
"",
|
|
93
93
|
].join("\n");
|
|
@@ -95,10 +95,10 @@ function buildDefaultTaskBody(): string {
|
|
|
95
95
|
|
|
96
96
|
|
|
97
97
|
export async function listTaskDefinitions(params: {
|
|
98
|
-
|
|
98
|
+
data_path: string;
|
|
99
99
|
status?: ShipTaskStatus;
|
|
100
100
|
}): Promise<TaskListResponse> {
|
|
101
|
-
const root = path.resolve(params.
|
|
101
|
+
const root = path.resolve(params.data_path);
|
|
102
102
|
const normalizedStatus = normalizeTaskStatus(params.status);
|
|
103
103
|
|
|
104
104
|
const tasks = await listTasks(root);
|
|
@@ -126,10 +126,10 @@ export async function listTaskDefinitions(params: {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
export async function createTaskDefinition(params: {
|
|
129
|
-
|
|
129
|
+
data_path: string;
|
|
130
130
|
request: TaskCreateRequest;
|
|
131
131
|
}): Promise<TaskCreateResponse> {
|
|
132
|
-
const root = path.resolve(params.
|
|
132
|
+
const root = path.resolve(params.data_path);
|
|
133
133
|
const req = params.request;
|
|
134
134
|
|
|
135
135
|
const title = String(req.title || "").trim();
|
|
@@ -178,7 +178,7 @@ export async function createTaskDefinition(params: {
|
|
|
178
178
|
try {
|
|
179
179
|
const written = await writeTask({
|
|
180
180
|
taskId: targetTaskId,
|
|
181
|
-
|
|
181
|
+
data_path: root,
|
|
182
182
|
overwrite: Boolean(req.overwrite) || Boolean(duplicated),
|
|
183
183
|
frontmatter: {
|
|
184
184
|
title,
|
|
@@ -206,15 +206,15 @@ export async function createTaskDefinition(params: {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
export async function updateTaskDefinition(params: {
|
|
209
|
-
|
|
209
|
+
data_path: string;
|
|
210
210
|
request: TaskUpdateRequest;
|
|
211
211
|
}): Promise<TaskUpdateResponse> {
|
|
212
|
-
const root = path.resolve(params.
|
|
212
|
+
const root = path.resolve(params.data_path);
|
|
213
213
|
const req = params.request;
|
|
214
214
|
const title = String(req.title || "").trim();
|
|
215
215
|
let taskId = "";
|
|
216
216
|
try {
|
|
217
|
-
taskId = await resolveTaskIdByTitle({
|
|
217
|
+
taskId = await resolveTaskIdByTitle({ data_path: root, title });
|
|
218
218
|
} catch (error) {
|
|
219
219
|
return { success: false, error: String(error) };
|
|
220
220
|
}
|
|
@@ -229,7 +229,7 @@ export async function updateTaskDefinition(params: {
|
|
|
229
229
|
|
|
230
230
|
try {
|
|
231
231
|
const current = await readTask({
|
|
232
|
-
|
|
232
|
+
data_path: root,
|
|
233
233
|
taskId,
|
|
234
234
|
});
|
|
235
235
|
|
|
@@ -291,7 +291,7 @@ export async function updateTaskDefinition(params: {
|
|
|
291
291
|
: current.body;
|
|
292
292
|
|
|
293
293
|
const written = await writeTask({
|
|
294
|
-
|
|
294
|
+
data_path: root,
|
|
295
295
|
taskId,
|
|
296
296
|
overwrite: true,
|
|
297
297
|
frontmatter: {
|
|
@@ -321,15 +321,15 @@ export async function updateTaskDefinition(params: {
|
|
|
321
321
|
|
|
322
322
|
export async function runTaskDefinition(params: {
|
|
323
323
|
context: PluginContext;
|
|
324
|
-
|
|
324
|
+
data_path: string;
|
|
325
325
|
request: TaskRunRequest;
|
|
326
326
|
execution_context?: PluginExecutionContext;
|
|
327
327
|
}): Promise<TaskRunResponse> {
|
|
328
|
-
const root = path.resolve(params.
|
|
328
|
+
const root = path.resolve(params.data_path);
|
|
329
329
|
const title = String(params.request.title || "").trim();
|
|
330
330
|
let taskId = "";
|
|
331
331
|
try {
|
|
332
|
-
taskId = await resolveTaskIdByTitle({
|
|
332
|
+
taskId = await resolveTaskIdByTitle({ data_path: root, title });
|
|
333
333
|
} catch (error) {
|
|
334
334
|
return { success: false, error: String(error) };
|
|
335
335
|
}
|
|
@@ -343,7 +343,7 @@ export async function runTaskDefinition(params: {
|
|
|
343
343
|
// 关键点(中文):run 改为“异步受理”,先做存在性校验,再后台执行。
|
|
344
344
|
await readTask({
|
|
345
345
|
taskId,
|
|
346
|
-
|
|
346
|
+
data_path: root,
|
|
347
347
|
});
|
|
348
348
|
|
|
349
349
|
params.context.logger.info(
|
|
@@ -358,7 +358,7 @@ export async function runTaskDefinition(params: {
|
|
|
358
358
|
const executionId = `${taskId}:${Date.now()}`;
|
|
359
359
|
void runTaskNow({
|
|
360
360
|
context: params.context,
|
|
361
|
-
|
|
361
|
+
data_path: root,
|
|
362
362
|
taskId,
|
|
363
363
|
trigger,
|
|
364
364
|
executionId,
|
|
@@ -417,14 +417,14 @@ export async function runTaskDefinition(params: {
|
|
|
417
417
|
}
|
|
418
418
|
|
|
419
419
|
export async function setTaskStatus(params: {
|
|
420
|
-
|
|
420
|
+
data_path: string;
|
|
421
421
|
request: TaskSetStatusRequest;
|
|
422
422
|
}): Promise<TaskSetStatusResponse> {
|
|
423
|
-
const root = path.resolve(params.
|
|
423
|
+
const root = path.resolve(params.data_path);
|
|
424
424
|
const title = String(params.request.title || "").trim();
|
|
425
425
|
let taskId = "";
|
|
426
426
|
try {
|
|
427
|
-
taskId = await resolveTaskIdByTitle({
|
|
427
|
+
taskId = await resolveTaskIdByTitle({ data_path: root, title });
|
|
428
428
|
} catch (error) {
|
|
429
429
|
return { success: false, error: String(error) };
|
|
430
430
|
}
|
|
@@ -439,12 +439,12 @@ export async function setTaskStatus(params: {
|
|
|
439
439
|
|
|
440
440
|
try {
|
|
441
441
|
const task = await readTask({
|
|
442
|
-
|
|
442
|
+
data_path: root,
|
|
443
443
|
taskId,
|
|
444
444
|
});
|
|
445
445
|
|
|
446
446
|
await writeTask({
|
|
447
|
-
|
|
447
|
+
data_path: root,
|
|
448
448
|
taskId,
|
|
449
449
|
overwrite: true,
|
|
450
450
|
frontmatter: {
|
|
@@ -468,21 +468,21 @@ export async function setTaskStatus(params: {
|
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
export async function deleteTaskDefinition(params: {
|
|
471
|
-
|
|
471
|
+
data_path: string;
|
|
472
472
|
request: TaskDeleteRequest;
|
|
473
473
|
}): Promise<TaskDeleteResponse> {
|
|
474
|
-
const root = path.resolve(params.
|
|
474
|
+
const root = path.resolve(params.data_path);
|
|
475
475
|
const title = String(params.request.title || "").trim();
|
|
476
476
|
let taskId = "";
|
|
477
477
|
try {
|
|
478
|
-
taskId = await resolveTaskIdByTitle({
|
|
478
|
+
taskId = await resolveTaskIdByTitle({ data_path: root, title });
|
|
479
479
|
} catch (error) {
|
|
480
480
|
return { success: false, error: String(error) };
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
try {
|
|
484
484
|
const deleted = await deleteTask({
|
|
485
|
-
|
|
485
|
+
data_path: root,
|
|
486
486
|
taskId,
|
|
487
487
|
});
|
|
488
488
|
return {
|
package/src/task/PROMPT.ts
CHANGED
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// Source: src/task/PROMPT.ts.txt
|
|
7
|
-
const TEXT_MODULE_CONTENT = "# Task Plugin\n\nYou can use the `task` plugin to manage task definitions, execution, scheduling, and status control.\n\n## Task Model\n\nEach task is defined in `./.downcity/task/<title>/task.md` and contains:\n- frontmatter for structured fields\n- body for the task instructions\n\nCore frontmatter fields:\n- `title`: unique task identifier\n- `description`: task description\n- `when`: trigger condition, supporting `@manual`, cron, or `time:<ISO8601-with-timezone>`\n- `session_id`: task execution session\n- `status`: `enabled|paused|disabled`\n- `kind`: `agent|script`, defaulting to `agent`\n\nEach execution creates a run directory:\n- `./.downcity/task/<title>/<timestamp>/`\n\nCommon artifacts:\n- `input.md`\n- `output.md`: final output body for this run\n- `result.md`: execution summary\n- `run.json`\n- `run-progress.json`\n- `dialogue.md` / `dialogue.json`: multi-turn agent dialogue\n- `error.md`: failure details\n\n## Execution Kinds\n\n1. `kind=agent`\n- Sends the task body to an agent for execution.\n- Completes in a single turn by default. Simulated multi-turn review is enabled only when frontmatter explicitly sets `review: true`.\n- Suitable for research, analysis, and report generation.\n\n2. `kind=script`\n- Treats the body as a shell script.\n- The body must be non-empty and executable as a script.\n\n## Available Actions\n\n- `list`\n- `create`\n- `run`\n- `delete`\n- `update`\n- `status`\n- `enable`\n- `disable`\n\n## Action Examples\n\n- `plugin_call({ plugin: \"task\", action: \"list\", payload: { status } })`\n- `plugin_call({ plugin: \"task\", action: \"create\", payload: { title, description, session_id, when, kind, status } })`\n- `plugin_call({ plugin: \"task\", action: \"run\", payload: { title, reason } })`\n- `plugin_call({ plugin: \"task\", action: \"update\", payload: { title, description, when, status, session_id } })`\n- `plugin_call({ plugin: \"task\", action: \"delete\", payload: { title } })`\n\n## Key Constraints\n\n- `title` is unique. `create` deduplicates only by exact `title`.\n- After `when=time:...` triggers, the task is automatically set to `paused` and falls back to `when=@manual`.\n- `run` is accepted asynchronously. It returns `accepted=true`, `message`, and `executionId` immediately. Treat this as \"the task has entered background execution; the result will be sent automatically through the chat plugin runtime, and the current flow does not need to block.\"\n- If `run` returns `accepted=true`:\n - Do not manually forward task output to the user again.\n - Do not actively poll the run directory, `run-progress.json`, or `output.md`.\n - Inspect the run directory only when the user explicitly asks to debug, view artifacts, or confirm execution details.\n- Agent tasks only need to produce valid output by default. They should send to an external channel only when the task body explicitly requires it.\n\n## Designing The Task Body\n\n### Recommended Agent Task Structure\n\nThe body should include at least these headings:\n\n```md\n# Task Goal\n\n- What final result this task must deliver.\n\n# Background And Input\n\n- Data sources, scope, constraints, and reference materials.\n\n# Execution Steps\n\n1. What to do first.\n2. What to do next.\n3. Where key intermediate artifacts should be written.\n\n# Output Requirements\n\n- What format the final result must use.\n- Whether a table, JSON, or Markdown is required.\n- What content must not be included.\n\n# Trigger And Status Recommendation\n\n- Why this task is suitable for `@manual`, cron, or `time:...`.\n- Whether it should currently be `paused` or `enabled`.\n\n# Notes\n\n- Risks, boundaries, and things not to do.\n```\n\n### Agent Task Body Writing Constraints\n\n- The task body must read like a delivery contract, so another executor can run it directly without relying on the current chat context.\n- `# Task Goal` must clearly state the final deliverable. Do not write vague goals such as \"take a look\", \"research this\", or \"handle this\".\n- `# Background And Input` must specify sources, scope, objects, time range, and constraints. Do not assume the executor can see the original chat context.\n- `# Execution Steps` should describe the task workflow, not task-management actions. Do not write \"first check whether a task with the same name exists\", \"then create a task\", or \"then trigger the task\".\n- `# Output Requirements` must clearly specify the final artifact's format, structure, tone, length, and excluded content.\n- Explicitly state that the final assistant message will be written directly to `output.md` and sent to the user. Therefore, the final answer must be exactly the deliverable content.\n- Content-generation tasks such as daily reports, reminders, morning briefings, summaries, and reports must explicitly require \"the final output is the deliverable body itself\". Do not let the executor output process notes.\n- If the task result should be sent to the user, the body should require \"output send-ready message content\" instead of asking the executor to explain what it has sent.\n- Unless truly needed, do not ask the executor to repeat the task title, session_id, execution time, status, or other metadata in the body.\n- Constraints in the body must be executable and checkable. Avoid weak phrases such as \"appropriately\", \"as much as possible\", or \"depending on the situation\".\n- Do not put task creation, task update, task status lookup, or same-title existence checks into the body. Those belong to the task plugin, not to the task deliverable.\n\n### Forbidden Agent Task Body Patterns\n\n- Do not write the body in chat-reply style, for example:\n - \"I will help you...\"\n - \"First, let me...\"\n - \"I will check first...\"\n - \"I see there is already a task with the same name...\"\n- Do not write the body as task-management instructions, for example:\n - \"If the task exists, update it; otherwise create it.\"\n - \"First list, then run.\"\n - \"Tell the user that the task has started when done.\"\n- Do not write the body as a status-report template, for example:\n - \"Task status summary\"\n - \"Sent / completed / updated\"\n - \"Current task configuration\"\n- Do not describe only actions without describing the deliverable, for example:\n - \"Go collect some materials.\"\n - \"Generate some content and see.\"\n - \"Report back after finishing.\"\n- Do not use references that depend on the current context, for example:\n - \"Do what was said above.\"\n - \"Continue the previous one.\"\n - \"Send this out.\"\n\n### How To Judge Whether The Body Is Good\n\n- If you can copy the task body alone to another agent and it can still understand the goal, input, steps, and deliverable, the body is valid.\n- If deleting the output section leaves only \"go do something\" style instructions, the body is invalid.\n- If the body looks more like instructions for creating or updating a task than instructions for executing the task, the layering is wrong and the body must be rewritten.\n- If the body naturally encourages the executor to output process notes instead of the final artifact, the `# Output Requirements` section is not strong enough and must add explicit prohibitions.\n\n### Recommended Script Task Structure\n\n- The body must be a pure shell script. Do not mix in explanatory natural language.\n- Start with comments that describe the script's purpose, input dependencies, and failure conditions when possible.\n- Keep output stable so it can be sent directly as the final result.\n- If files need to be generated, write them to the run directory or to an explicit project path.\n\n### Output Design Principles\n\n- When a task completes, the system automatically sends the final result body back to the chat bound to `session_id` through the chat plugin runtime's `send`.\n- The current implementation uses the simplest rule: the final assistant message is treated directly as the final result body and written to `output.md`.\n- Therefore, the \"Output Requirements\" section must be written for the final user, not only for developers.\n- For user-facing agent tasks, the body should require \"the final assistant message directly outputs the deliverable itself\". Do not let the executor explain how it created, checked, updated, triggered, or sent the task.\n- For content-generation tasks such as daily reports, reminders, morning briefings, and summaries, the final output should be exactly that content. It should not include process language such as \"I will handle this\", \"task sent\", or \"task status summary\".\n- By default, do not ask the executor to call chat plugin send actions again. The system handles final-result delivery.\n- Explicitly require chat plugin actions only for cross-conversation sending, additional CCs, multi-channel notifications, or similar cases.\n\n### Choosing `when` And `status`\n\n- A task is created as `status=enabled` by default. Set `paused` explicitly only when it is still a draft, likely to fail, or needs human confirmation.\n- For verified stable tasks that need automatic execution, use cron with `status=enabled`.\n- For a clear one-time execution, use `time:<ISO time with timezone>`. After execution, the system automatically falls back to `@manual` and `paused`.\n- If the user only wants to save it for later, do not enable scheduling directly.\n\n## Body Templates\n\n### Agent Template\n\n```md\n# Task Goal\n\n- Produce a final result that can be sent directly to the user.\n\n# Background And Input\n\n- Add context, files, links, scope, and assumptions here.\n\n# Execution Steps\n\n1. Understand the task goal and completion criteria.\n2. Collect necessary information and execute the task.\n3. Write key intermediate artifacts to the run directory.\n4. Output the final result body.\n\n# Output Requirements\n\n- The final assistant message is the final result. Do not include long logs.\n- The final assistant message must output the deliverable itself. Do not output task-management process, sending process, or status reports.\n- Do not use meta language such as \"I will help you...\", \"First, let me...\", or \"sent\".\n- By default, do not call the chat plugin send action again.\n\n# Trigger And Status Recommendation\n\n- Enable by default after creation. If this is only a draft or waiting for human confirmation, set it to `paused`.\n\n# Notes\n\n- Call chat plugin send actions only when cross-conversation or additional notifications are explicitly needed.\n```\n\n### Script Template\n\n```bash\n# Task goal: state in one sentence what the script should do\n# Input dependencies: list environment variables, files, and command dependencies\n# Failure conditions: list cases that should exit 1\n\nset -euo pipefail\n\n# 1. Prepare input\n\n# 2. Execute main logic\n\n# 3. Output final result. This output will be sent directly to the user.\n```\n\n## Recommendations\n\n- Run `list` before `create` or `update`.\n- Keep simple content-generation tasks single-turn by default. Set `review: true` only when you truly need \"draft, review, revise\".\n- Keep script task bodies as pure scripts, without redundant natural-language explanation.\n- If the user only wants to save something for later, create it as `paused`; otherwise keep the default enabled state.\n- The task body must describe what the final result should look like, not only say \"go do this and see\".\n- For content-generation tasks, explicitly require \"the final assistant message can only be the finished content body\" so the executor does not mistake process notes for the final result.\n";
|
|
7
|
+
const TEXT_MODULE_CONTENT = "# Task Plugin\n\nYou can use the `task` plugin to manage task definitions, execution, scheduling, and status control.\n\n## Task Model\n\nEach task is defined in the current Agent private runtime directory private `task/<title>/task.md` and contains:\n- frontmatter for structured fields\n- body for the task instructions\n\nCore frontmatter fields:\n- `title`: unique task identifier\n- `description`: task description\n- `when`: trigger condition, supporting `@manual`, cron, or `time:<ISO8601-with-timezone>`\n- `session_id`: task execution session\n- `status`: `enabled|paused|disabled`\n- `kind`: `agent|script`, defaulting to `agent`\n\nEach execution creates a private run record managed by Downcity under the current Agent private runtime directory.\n\nCommon artifacts:\n- `input.md`\n- `output.md`: final output body for this run\n- `result.md`: execution summary\n- `run.json`\n- `run-progress.json`\n- `dialogue.md` / `dialogue.json`: multi-turn agent dialogue\n- `error.md`: failure details\n\n## Execution Kinds\n\n1. `kind=agent`\n- Sends the task body to an agent for execution.\n- Completes in a single turn by default. Simulated multi-turn review is enabled only when frontmatter explicitly sets `review: true`.\n- Suitable for research, analysis, and report generation.\n\n2. `kind=script`\n- Treats the body as a shell script.\n- The body must be non-empty and executable as a script.\n\n## Available Actions\n\n- `list`\n- `create`\n- `run`\n- `delete`\n- `update`\n- `status`\n- `enable`\n- `disable`\n\n## Action Examples\n\n- `plugin_call({ plugin: \"task\", action: \"list\", payload: { status } })`\n- `plugin_call({ plugin: \"task\", action: \"create\", payload: { title, description, session_id, when, kind, status } })`\n- `plugin_call({ plugin: \"task\", action: \"run\", payload: { title, reason } })`\n- `plugin_call({ plugin: \"task\", action: \"update\", payload: { title, description, when, status, session_id } })`\n- `plugin_call({ plugin: \"task\", action: \"delete\", payload: { title } })`\n\n## Key Constraints\n\n- `title` is unique. `create` deduplicates only by exact `title`.\n- After `when=time:...` triggers, the task is automatically set to `paused` and falls back to `when=@manual`.\n- `run` is accepted asynchronously. It returns `accepted=true`, `message`, and `executionId` immediately. Treat this as \"the task has entered background execution; the result will be sent automatically through the chat plugin runtime, and the current flow does not need to block.\"\n- If `run` returns `accepted=true`:\n - Do not manually forward task output to the user again.\n - Do not actively poll the run directory, `run-progress.json`, or `output.md`.\n - Inspect run details through the task/control API only when the user explicitly asks to debug, view artifacts, or confirm execution details.\n- Agent tasks only need to produce valid output by default. They should send to an external channel only when the task body explicitly requires it.\n\n## Designing The Task Body\n\n### Recommended Agent Task Structure\n\nThe body should include at least these headings:\n\n```md\n# Task Goal\n\n- What final result this task must deliver.\n\n# Background And Input\n\n- Data sources, scope, constraints, and reference materials.\n\n# Execution Steps\n\n1. What to do first.\n2. What to do next.\n3. Where key intermediate artifacts should be written.\n\n# Output Requirements\n\n- What format the final result must use.\n- Whether a table, JSON, or Markdown is required.\n- What content must not be included.\n\n# Trigger And Status Recommendation\n\n- Why this task is suitable for `@manual`, cron, or `time:...`.\n- Whether it should currently be `paused` or `enabled`.\n\n# Notes\n\n- Risks, boundaries, and things not to do.\n```\n\n### Agent Task Body Writing Constraints\n\n- The task body must read like a delivery contract, so another executor can run it directly without relying on the current chat context.\n- `# Task Goal` must clearly state the final deliverable. Do not write vague goals such as \"take a look\", \"research this\", or \"handle this\".\n- `# Background And Input` must specify sources, scope, objects, time range, and constraints. Do not assume the executor can see the original chat context.\n- `# Execution Steps` should describe the task workflow, not task-management actions. Do not write \"first check whether a task with the same name exists\", \"then create a task\", or \"then trigger the task\".\n- `# Output Requirements` must clearly specify the final artifact's format, structure, tone, length, and excluded content.\n- Explicitly state that the final assistant message will be written directly to `output.md` and sent to the user. Therefore, the final answer must be exactly the deliverable content.\n- Content-generation tasks such as daily reports, reminders, morning briefings, summaries, and reports must explicitly require \"the final output is the deliverable body itself\". Do not let the executor output process notes.\n- If the task result should be sent to the user, the body should require \"output send-ready message content\" instead of asking the executor to explain what it has sent.\n- Unless truly needed, do not ask the executor to repeat the task title, session_id, execution time, status, or other metadata in the body.\n- Constraints in the body must be executable and checkable. Avoid weak phrases such as \"appropriately\", \"as much as possible\", or \"depending on the situation\".\n- Do not put task creation, task update, task status lookup, or same-title existence checks into the body. Those belong to the task plugin, not to the task deliverable.\n\n### Forbidden Agent Task Body Patterns\n\n- Do not write the body in chat-reply style, for example:\n - \"I will help you...\"\n - \"First, let me...\"\n - \"I will check first...\"\n - \"I see there is already a task with the same name...\"\n- Do not write the body as task-management instructions, for example:\n - \"If the task exists, update it; otherwise create it.\"\n - \"First list, then run.\"\n - \"Tell the user that the task has started when done.\"\n- Do not write the body as a status-report template, for example:\n - \"Task status summary\"\n - \"Sent / completed / updated\"\n - \"Current task configuration\"\n- Do not describe only actions without describing the deliverable, for example:\n - \"Go collect some materials.\"\n - \"Generate some content and see.\"\n - \"Report back after finishing.\"\n- Do not use references that depend on the current context, for example:\n - \"Do what was said above.\"\n - \"Continue the previous one.\"\n - \"Send this out.\"\n\n### How To Judge Whether The Body Is Good\n\n- If you can copy the task body alone to another agent and it can still understand the goal, input, steps, and deliverable, the body is valid.\n- If deleting the output section leaves only \"go do something\" style instructions, the body is invalid.\n- If the body looks more like instructions for creating or updating a task than instructions for executing the task, the layering is wrong and the body must be rewritten.\n- If the body naturally encourages the executor to output process notes instead of the final artifact, the `# Output Requirements` section is not strong enough and must add explicit prohibitions.\n\n### Recommended Script Task Structure\n\n- The body must be a pure shell script. Do not mix in explanatory natural language.\n- Start with comments that describe the script's purpose, input dependencies, and failure conditions when possible.\n- Keep output stable so it can be sent directly as the final result.\n- If files need to be delivered to the user, write them to an explicit project path.\n\n### Output Design Principles\n\n- When a task completes, the system automatically sends the final result body back to the chat bound to `session_id` through the chat plugin runtime's `send`.\n- The current implementation uses the simplest rule: the final assistant message is treated directly as the final result body and written to `output.md`.\n- Therefore, the \"Output Requirements\" section must be written for the final user, not only for developers.\n- For user-facing agent tasks, the body should require \"the final assistant message directly outputs the deliverable itself\". Do not let the executor explain how it created, checked, updated, triggered, or sent the task.\n- For content-generation tasks such as daily reports, reminders, morning briefings, and summaries, the final output should be exactly that content. It should not include process language such as \"I will handle this\", \"task sent\", or \"task status summary\".\n- By default, do not ask the executor to call chat plugin send actions again. The system handles final-result delivery.\n- Explicitly require chat plugin actions only for cross-conversation sending, additional CCs, multi-channel notifications, or similar cases.\n\n### Choosing `when` And `status`\n\n- A task is created as `status=enabled` by default. Set `paused` explicitly only when it is still a draft, likely to fail, or needs human confirmation.\n- For verified stable tasks that need automatic execution, use cron with `status=enabled`.\n- For a clear one-time execution, use `time:<ISO time with timezone>`. After execution, the system automatically falls back to `@manual` and `paused`.\n- If the user only wants to save it for later, do not enable scheduling directly.\n\n## Body Templates\n\n### Agent Template\n\n```md\n# Task Goal\n\n- Produce a final result that can be sent directly to the user.\n\n# Background And Input\n\n- Add context, files, links, scope, and assumptions here.\n\n# Execution Steps\n\n1. Understand the task goal and completion criteria.\n2. Collect necessary information and execute the task.\n3. Write user-visible artifacts to an explicit project path when needed.\n4. Output the final result body.\n\n# Output Requirements\n\n- The final assistant message is the final result. Do not include long logs.\n- The final assistant message must output the deliverable itself. Do not output task-management process, sending process, or status reports.\n- Do not use meta language such as \"I will help you...\", \"First, let me...\", or \"sent\".\n- By default, do not call the chat plugin send action again.\n\n# Trigger And Status Recommendation\n\n- Enable by default after creation. If this is only a draft or waiting for human confirmation, set it to `paused`.\n\n# Notes\n\n- Call chat plugin send actions only when cross-conversation or additional notifications are explicitly needed.\n```\n\n### Script Template\n\n```bash\n# Task goal: state in one sentence what the script should do\n# Input dependencies: list environment variables, files, and command dependencies\n# Failure conditions: list cases that should exit 1\n\nset -euo pipefail\n\n# 1. Prepare input\n\n# 2. Execute main logic\n\n# 3. Output final result. This output will be sent directly to the user.\n```\n\n## Recommendations\n\n- Run `list` before `create` or `update`.\n- Keep simple content-generation tasks single-turn by default. Set `review: true` only when you truly need \"draft, review, revise\".\n- Keep script task bodies as pure scripts, without redundant natural-language explanation.\n- If the user only wants to save something for later, create it as `paused`; otherwise keep the default enabled state.\n- The task body must describe what the final result should look like, not only say \"go do this and see\".\n- For content-generation tasks, explicitly require \"the final assistant message can only be the finished content body\" so the executor does not mistake process notes for the final result.\n";
|
|
8
8
|
|
|
9
9
|
export default TEXT_MODULE_CONTENT;
|
package/src/task/PROMPT.ts.txt
CHANGED
|
@@ -4,7 +4,7 @@ You can use the `task` plugin to manage task definitions, execution, scheduling,
|
|
|
4
4
|
|
|
5
5
|
## Task Model
|
|
6
6
|
|
|
7
|
-
Each task is defined in
|
|
7
|
+
Each task is defined in the current Agent private runtime directory private `task/<title>/task.md` and contains:
|
|
8
8
|
- frontmatter for structured fields
|
|
9
9
|
- body for the task instructions
|
|
10
10
|
|
|
@@ -16,8 +16,7 @@ Core frontmatter fields:
|
|
|
16
16
|
- `status`: `enabled|paused|disabled`
|
|
17
17
|
- `kind`: `agent|script`, defaulting to `agent`
|
|
18
18
|
|
|
19
|
-
Each execution creates a run directory
|
|
20
|
-
- `./.downcity/task/<title>/<timestamp>/`
|
|
19
|
+
Each execution creates a private run record managed by Downcity under the current Agent private runtime directory.
|
|
21
20
|
|
|
22
21
|
Common artifacts:
|
|
23
22
|
- `input.md`
|
|
@@ -66,7 +65,7 @@ Common artifacts:
|
|
|
66
65
|
- If `run` returns `accepted=true`:
|
|
67
66
|
- Do not manually forward task output to the user again.
|
|
68
67
|
- Do not actively poll the run directory, `run-progress.json`, or `output.md`.
|
|
69
|
-
- Inspect the
|
|
68
|
+
- Inspect run details through the task/control API only when the user explicitly asks to debug, view artifacts, or confirm execution details.
|
|
70
69
|
- Agent tasks only need to produce valid output by default. They should send to an external channel only when the task body explicitly requires it.
|
|
71
70
|
|
|
72
71
|
## Designing The Task Body
|
|
@@ -156,7 +155,7 @@ The body should include at least these headings:
|
|
|
156
155
|
- The body must be a pure shell script. Do not mix in explanatory natural language.
|
|
157
156
|
- Start with comments that describe the script's purpose, input dependencies, and failure conditions when possible.
|
|
158
157
|
- Keep output stable so it can be sent directly as the final result.
|
|
159
|
-
- If files need to be
|
|
158
|
+
- If files need to be delivered to the user, write them to an explicit project path.
|
|
160
159
|
|
|
161
160
|
### Output Design Principles
|
|
162
161
|
|
|
@@ -192,7 +191,7 @@ The body should include at least these headings:
|
|
|
192
191
|
|
|
193
192
|
1. Understand the task goal and completion criteria.
|
|
194
193
|
2. Collect necessary information and execute the task.
|
|
195
|
-
3. Write
|
|
194
|
+
3. Write user-visible artifacts to an explicit project path when needed.
|
|
196
195
|
4. Output the final result body.
|
|
197
196
|
|
|
198
197
|
# Output Requirements
|
package/src/task/Scheduler.ts
CHANGED
|
@@ -36,7 +36,7 @@ export async function registerTaskCronJobs(params: {
|
|
|
36
36
|
}): Promise<{ tasksFound: number; jobsScheduled: number }> {
|
|
37
37
|
const context = params.context;
|
|
38
38
|
const logger = context.logger;
|
|
39
|
-
const tasks = await listTasks(context.
|
|
39
|
+
const tasks = await listTasks(context.data_path);
|
|
40
40
|
const runtimeTimezone = params.timezone;
|
|
41
41
|
|
|
42
42
|
let jobsScheduled = 0;
|
|
@@ -49,7 +49,7 @@ export async function registerTaskCronJobs(params: {
|
|
|
49
49
|
try {
|
|
50
50
|
const task = await readTask({
|
|
51
51
|
taskId: item.taskId,
|
|
52
|
-
|
|
52
|
+
data_path: context.data_path,
|
|
53
53
|
});
|
|
54
54
|
latestWhen = task.frontmatter.when;
|
|
55
55
|
} catch {}
|
|
@@ -78,7 +78,7 @@ export async function registerTaskCronJobs(params: {
|
|
|
78
78
|
// 关键点(中文):触发瞬间复查最新 task.md,避免 status/when 变更后仍沿用旧注册状态。
|
|
79
79
|
const latest = await readTask({
|
|
80
80
|
taskId,
|
|
81
|
-
|
|
81
|
+
data_path: context.data_path,
|
|
82
82
|
});
|
|
83
83
|
if (String(latest.frontmatter.status).toLowerCase() !== "enabled") {
|
|
84
84
|
return;
|
|
@@ -91,7 +91,7 @@ export async function registerTaskCronJobs(params: {
|
|
|
91
91
|
const result = await runTaskNow({
|
|
92
92
|
context,
|
|
93
93
|
taskId,
|
|
94
|
-
|
|
94
|
+
data_path: context.data_path,
|
|
95
95
|
trigger: { type: "cron" },
|
|
96
96
|
});
|
|
97
97
|
|
|
@@ -166,7 +166,7 @@ export async function registerTaskCronJobs(params: {
|
|
|
166
166
|
try {
|
|
167
167
|
const latest = await readTask({
|
|
168
168
|
taskId,
|
|
169
|
-
|
|
169
|
+
data_path: context.data_path,
|
|
170
170
|
});
|
|
171
171
|
if (String(latest.frontmatter.status).toLowerCase() !== "enabled") return;
|
|
172
172
|
const latestPlannedMs = resolveTaskWhenOneShotMs(latest.frontmatter.when);
|
|
@@ -177,7 +177,7 @@ export async function registerTaskCronJobs(params: {
|
|
|
177
177
|
const result = await runTaskNow({
|
|
178
178
|
context,
|
|
179
179
|
taskId,
|
|
180
|
-
|
|
180
|
+
data_path: context.data_path,
|
|
181
181
|
trigger: { type: "time" },
|
|
182
182
|
});
|
|
183
183
|
|
|
@@ -206,10 +206,10 @@ export async function registerTaskCronJobs(params: {
|
|
|
206
206
|
try {
|
|
207
207
|
const latest = await readTask({
|
|
208
208
|
taskId,
|
|
209
|
-
|
|
209
|
+
data_path: context.data_path,
|
|
210
210
|
});
|
|
211
211
|
await writeTask({
|
|
212
|
-
|
|
212
|
+
data_path: context.data_path,
|
|
213
213
|
taskId,
|
|
214
214
|
overwrite: true,
|
|
215
215
|
frontmatter: {
|