UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

274 lines 11.2 kB
/** * Built-in agent tools for TaskManager. * * These tools allow the AI to self-schedule, manage, and inspect tasks * during conversations. Created per-instance via `createTaskTools()` factory, * following the same pattern as `createFileTools()` in files/fileTools.ts. * * @module tasks/tools/taskTools */ import { tool } from "ai"; import { z } from "zod"; import { logger } from "../../utils/logger.js"; import { TaskError } from "../errors.js"; /** * Parse a schedule object from tool input. * Accepts: { type: "cron", expression } | { type: "interval", every } | { type: "once", at } */ function parseSchedule(input) { const type = input.type; if (type === "cron") { if (!input.expression || typeof input.expression !== "string") { throw TaskError.create("SCHEDULE_FAILED", "Cron schedule requires an 'expression' field"); } return { type: "cron", expression: input.expression, ...(input.timezone ? { timezone: input.timezone } : {}), }; } if (type === "interval") { if (typeof input.every !== "number" || !isFinite(input.every) || input.every <= 0) { throw TaskError.create("SCHEDULE_FAILED", "Interval schedule requires a positive 'every' field (milliseconds)"); } return { type: "interval", every: input.every }; } if (type === "once") { if (!input.at) { throw TaskError.create("SCHEDULE_FAILED", "Once schedule requires an 'at' field (ISO 8601 date string)"); } return { type: "once", at: input.at }; } throw TaskError.create("SCHEDULE_FAILED", `Invalid schedule type: "${type}". Must be "cron", "interval", or "once".`); } /** * Create task management tools bound to a TaskManager instance. * * These tools follow the same factory pattern as `createFileTools()` in * `src/lib/files/fileTools.ts`. The `manager` is captured via closure, * eliminating the need for module-level singleton state. * * @param manager - The TaskManager instance to bind to * @returns Record of tool name to tool definition * * @example * ```typescript * const manager = new TaskManager(neurolink, config); * const tools = createTaskTools(manager); * // tools.createTask, tools.listTasks, tools.getTaskRuns, etc. * ``` */ export function createTaskTools(manager) { return { createTask: tool({ description: 'Schedule a recurring or one-shot task that runs a prompt on a schedule. Use schedule type "cron" for calendar-based (e.g. "0 9 * * *"), "interval" for fixed frequency (every N milliseconds), or "once" for a single future execution.', inputSchema: z.object({ name: z.string().describe("Human-readable task name"), prompt: z.string().describe("The prompt to execute on each run"), schedule: z .object({ type: z.enum(["cron", "interval", "once"]), expression: z .string() .optional() .describe('Cron expression (for type "cron"), e.g. "0 9 * * *"'), timezone: z .string() .optional() .describe('IANA timezone for cron, e.g. "America/New_York"'), every: z .number() .optional() .describe('Interval in milliseconds (for type "interval")'), at: z .string() .optional() .describe('ISO 8601 timestamp (for type "once")'), }) .describe("When to run the task"), mode: z .enum(["isolated", "continuation"]) .optional() .describe('Execution mode. "isolated" = fresh context per run (default). "continuation" = preserves conversation history across runs.'), }), execute: async ({ name, prompt, schedule, mode }) => { try { const parsedSchedule = parseSchedule(schedule); const task = await manager.create({ name, prompt, schedule: parsedSchedule, mode: mode, }); return { success: true, taskId: task.id, name: task.name, status: task.status, mode: task.mode, nextRunAt: task.nextRunAt, schedule: task.schedule, }; } catch (error) { logger.error("[taskTools] createTask failed", { error: String(error), }); return { success: false, error: error instanceof Error ? error.message : String(error), }; } }, }), listTasks: tool({ description: "List all scheduled tasks and their current status.", inputSchema: z.object({ status: z .enum([ "active", "paused", "completed", "failed", "cancelled", "pending", ]) .optional() .describe("Filter by task status"), }), execute: async ({ status }) => { try { const tasks = await manager.list(status ? { status: status, } : undefined); return { success: true, count: tasks.length, tasks: tasks.map((t) => ({ taskId: t.id, name: t.name, status: t.status, mode: t.mode, schedule: t.schedule, runCount: t.runCount, lastRunAt: t.lastRunAt, nextRunAt: t.nextRunAt, })), }; } catch (error) { logger.error("[taskTools] listTasks failed", { error: String(error), }); return { success: false, error: error instanceof Error ? error.message : String(error), }; } }, }), getTaskRuns: tool({ description: "Get the run history of a scheduled task, showing recent executions and their results.", inputSchema: z.object({ taskId: z.string().describe("The task ID"), limit: z .number() .optional() .describe("Max results to return (default: 10)"), }), execute: async ({ taskId, limit }) => { try { const runs = await manager.runs(taskId, { limit: limit ?? 10 }); return { success: true, taskId, count: runs.length, runs: runs.map((r) => ({ runId: r.runId, status: r.status, output: r.output ? r.output.length > 500 ? r.output.slice(0, 500) + "..." : r.output : undefined, durationMs: r.durationMs, timestamp: r.timestamp, error: r.error, })), }; } catch (error) { logger.error("[taskTools] getTaskRuns failed", { error: String(error), }); return { success: false, error: error instanceof Error ? error.message : String(error), }; } }, }), deleteTask: tool({ description: "Cancel and permanently remove a scheduled task.", inputSchema: z.object({ taskId: z.string().describe("The task ID to delete"), }), execute: async ({ taskId }) => { try { const task = await manager.get(taskId); if (!task) { return { success: false, error: `Task not found: ${taskId}` }; } await manager.delete(taskId); return { success: true, deletedTask: task.name, taskId }; } catch (error) { logger.error("[taskTools] deleteTask failed", { error: String(error), }); return { success: false, error: error instanceof Error ? error.message : String(error), }; } }, }), runTaskNow: tool({ description: "Immediately execute a scheduled task outside of its normal schedule. Returns the run result.", inputSchema: z.object({ taskId: z.string().describe("The task ID to run"), }), execute: async ({ taskId }) => { try { const result = await manager.run(taskId); return { success: true, runId: result.runId, status: result.status, output: result.output ? result.output.length > 1000 ? result.output.slice(0, 1000) + "..." : result.output : undefined, durationMs: result.durationMs, error: result.error, }; } catch (error) { logger.error("[taskTools] runTaskNow failed", { error: String(error), }); return { success: false, error: error instanceof Error ? error.message : String(error), }; } }, }), }; } //# sourceMappingURL=taskTools.js.map