feat: add proactive messaging support in CronJobPage and enhance file download tool with user notification option
This commit is contained in:
@@ -144,7 +144,11 @@ class FileDownloadTool(FunctionTool):
|
||||
"remote_path": {
|
||||
"type": "string",
|
||||
"description": "The path of the file in the sandbox to download.",
|
||||
}
|
||||
},
|
||||
"also_send_to_user": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to also send the downloaded file to the user via message. Defaults to true.",
|
||||
},
|
||||
},
|
||||
"required": ["remote_path"],
|
||||
}
|
||||
@@ -154,6 +158,7 @@ class FileDownloadTool(FunctionTool):
|
||||
self,
|
||||
context: ContextWrapper[AstrAgentContext],
|
||||
remote_path: str,
|
||||
also_send_to_user: bool = True,
|
||||
) -> ToolExecResult:
|
||||
sb = await get_booter(
|
||||
context.context.context,
|
||||
@@ -168,13 +173,14 @@ class FileDownloadTool(FunctionTool):
|
||||
await sb.download_file(remote_path, local_path)
|
||||
logger.info(f"File {remote_path} downloaded from sandbox to {local_path}")
|
||||
|
||||
try:
|
||||
name = os.path.basename(local_path)
|
||||
await context.context.event.send(
|
||||
MessageChain(chain=[File(name=name, file=local_path)])
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending file message: {e}")
|
||||
if also_send_to_user:
|
||||
try:
|
||||
name = os.path.basename(local_path)
|
||||
await context.context.event.send(
|
||||
MessageChain(chain=[File(name=name, file=local_path)])
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error sending file message: {e}")
|
||||
|
||||
# remove
|
||||
try:
|
||||
|
||||
@@ -90,6 +90,14 @@ class Platform(abc.ABC):
|
||||
def get_stats(self) -> dict:
|
||||
"""获取平台统计信息"""
|
||||
meta = self.meta()
|
||||
meta_info = {
|
||||
"id": meta.id,
|
||||
"name": meta.name,
|
||||
"display_name": meta.adapter_display_name or meta.name,
|
||||
"description": meta.description,
|
||||
"support_streaming_message": meta.support_streaming_message,
|
||||
"support_proactive_message": meta.support_proactive_message,
|
||||
}
|
||||
return {
|
||||
"id": meta.id or self.config.get("id"),
|
||||
"type": meta.name,
|
||||
@@ -105,6 +113,7 @@ class Platform(abc.ABC):
|
||||
if self.last_error
|
||||
else None,
|
||||
"unified_webhook": self.unified_webhook(),
|
||||
"meta": meta_info,
|
||||
}
|
||||
|
||||
@abc.abstractmethod
|
||||
|
||||
@@ -86,6 +86,7 @@ class WebChatAdapter(Platform):
|
||||
name="webchat",
|
||||
description="webchat",
|
||||
id="webchat",
|
||||
support_proactive_message=False,
|
||||
)
|
||||
|
||||
async def send_by_session(
|
||||
|
||||
@@ -43,25 +43,15 @@ const sidebarItem: menu[] = [
|
||||
icon: 'mdi-book-open-variant',
|
||||
to: '/knowledge-base',
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.persona',
|
||||
icon: 'mdi-heart',
|
||||
to: '/persona'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.groups.more',
|
||||
icon: 'mdi-dots-horizontal',
|
||||
children: [
|
||||
{
|
||||
title: 'core.navigation.persona',
|
||||
icon: 'mdi-heart',
|
||||
to: '/persona'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.subagent',
|
||||
icon: 'mdi-vector-link',
|
||||
to: '/subagent'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.cron',
|
||||
icon: 'mdi-clock-outline',
|
||||
to: '/cron'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.conversation',
|
||||
icon: 'mdi-database',
|
||||
@@ -72,6 +62,16 @@ const sidebarItem: menu[] = [
|
||||
icon: 'mdi-pencil-ruler',
|
||||
to: '/session-management'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.cron',
|
||||
icon: 'mdi-clock-outline',
|
||||
to: '/cron'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.subagent',
|
||||
icon: 'mdi-vector-link',
|
||||
to: '/subagent'
|
||||
},
|
||||
{
|
||||
title: 'core.navigation.dashboard',
|
||||
icon: 'mdi-view-dashboard',
|
||||
|
||||
@@ -6,7 +6,14 @@
|
||||
<h2 class="text-h5 font-weight-bold">未来任务管理</h2>
|
||||
<v-chip size="x-small" color="orange-darken-2" variant="tonal" label>Beta</v-chip>
|
||||
</div>
|
||||
<div class="text-body-2 text-medium-emphasis">查看给 AstrBot 布置的未来任务。AstrBot 将会被自动唤醒、执行任务,然后将结果告知任务布置方。</div>
|
||||
<div class="text-body-2 text-medium-emphasis">
|
||||
查看给 AstrBot 布置的未来任务。AstrBot 将会被自动唤醒、执行任务,然后将结果告知任务布置方。
|
||||
主动发送结果仅支持以下平台:
|
||||
<span v-if="proactivePlatforms.length">
|
||||
{{ proactivePlatforms.map((p) => `${p.display_name || p.name}(${p.id})`).join('、') }}
|
||||
</span>
|
||||
<span v-else>暂无支持主动消息的平台,请在平台设置中开启。</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center" style="gap: 8px;">
|
||||
<v-btn variant="tonal" color="primary" :loading="loading" @click="loadJobs">刷新</v-btn>
|
||||
@@ -60,6 +67,7 @@ import axios from 'axios'
|
||||
|
||||
const loading = ref(false)
|
||||
const jobs = ref<any[]>([])
|
||||
const proactivePlatforms = ref<{ id: string; name: string; display_name?: string }[]>([])
|
||||
|
||||
const snackbar = ref({ show: false, message: '', color: 'success' })
|
||||
|
||||
@@ -102,6 +110,23 @@ async function loadJobs() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPlatforms() {
|
||||
try {
|
||||
const res = await axios.get('/api/platform/stats')
|
||||
if (res.data.status === 'ok' && Array.isArray(res.data.data?.platforms)) {
|
||||
proactivePlatforms.value = res.data.data.platforms
|
||||
.filter((p: any) => p?.meta?.support_proactive_message)
|
||||
.map((p: any) => ({
|
||||
id: p?.id || p?.meta?.id || 'unknown',
|
||||
name: p?.meta?.name || p?.type || '',
|
||||
display_name: p?.meta?.display_name || p?.display_name
|
||||
}))
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore platform fetch errors in UI; subtitle will show fallback
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleJob(job: any) {
|
||||
try {
|
||||
const res = await axios.patch(`/api/cron/jobs/${job.job_id}`, { enabled: job.enabled })
|
||||
@@ -131,6 +156,7 @@ async function deleteJob(job: any) {
|
||||
|
||||
onMounted(() => {
|
||||
loadJobs()
|
||||
loadPlatforms()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user