| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- // 定时任务工具(docs/design/14-schedules.md §4):由 MCP Gateway 提供给所有会话(普通会话与工作组中的机器人)
- import { z } from 'zod'
- import { fail, ok, type BuiltinTool, type ToolResult } from '../mcp-gateway/builtin'
- import type { GatewayRunContext } from '../mcp-gateway/tokens'
- const scheduleArg = z.object({
- kind: z.enum(['once', 'daily', 'weekdays', 'weekly', 'monthly', 'interval'])
- .describe('once:只执行一次;daily:每天;weekdays:周一到周五;weekly:每周的某几天;monthly:每月某天;interval:每 N 小时'),
- time: z.string().optional().describe('daily / weekdays / weekly / monthly 的执行时间,HH:mm(24 小时制)'),
- days: z.array(z.number().int()).optional().describe('weekly 的星期几,1=周一 … 7=周日'),
- day: z.number().int().optional().describe('monthly 的日期 1–31,超过当月天数时取最后一天'),
- at: z.string().optional().describe('once 的执行时间,YYYY-MM-DD HH:mm'),
- after_minutes: z.number().optional().describe('once 的另一种写法:多少分钟后执行(用户说"两小时后"等相对时间时使用)'),
- hours: z.number().optional().describe('interval 的间隔小时数'),
- })
- const schemasFor = (timezone: string) => ({
- schedule_create: z.object({
- title: z.string().min(1).max(60).describe('简短的名称,如"销售日报"'),
- prompt: z.string().min(1).max(20_000).describe('到点时发给你的完整指令:要能独立执行,写清楚做什么、数据从哪里来、产出放在哪里'),
- schedule: scheduleArg.describe(`时间表,时间按 ${timezone} 时区`),
- }),
- schedule_list: z.object({}),
- schedule_update: z.object({
- schedule_id: z.string().describe('定时任务 id(见 schedule_list)'),
- title: z.string().max(60).optional(),
- prompt: z.string().max(20_000).optional(),
- schedule: scheduleArg.describe(`时间表,时间按 ${timezone} 时区`).optional(),
- status: z.enum(['active', 'paused']).optional().describe('暂停或恢复'),
- }),
- schedule_delete: z.object({ schedule_id: z.string() }),
- })
- type ToolName = keyof ReturnType<typeof schemasFor>
- const DESCRIPTIONS: Record<ToolName, string> = {
- schedule_create: '用户要求定期执行或在将来某个时间执行某项工作时,创建定时任务。会显示确认卡片,用户确认后生效;到点时系统把 prompt 作为一条新消息发到当前会话(工作组中发到工作组),由你执行。',
- schedule_list: '列出当前会话(或工作组)的定时任务。',
- schedule_update: '修改定时任务的名称、指令或时间表(需要用户确认),或者暂停、恢复(不需要确认)。',
- schedule_delete: '删除定时任务。',
- }
- export function scheduleTools(timezone: string, handle: (name: ToolName, args: Record<string, unknown>, ctx: GatewayRunContext) => Promise<string>): BuiltinTool[] {
- const schemas = schemasFor(timezone)
- return (Object.keys(schemas) as ToolName[]).map(name => ({
- name,
- description: DESCRIPTIONS[name],
- schema: schemas[name],
- readOnly: name === 'schedule_list',
- async handler(args, ctx): Promise<ToolResult> {
- try {
- return ok(await handle(name, args as Record<string, unknown>, ctx))
- } catch (err) {
- return fail((err as Error).message)
- }
- },
- }))
- }
|