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

314 lines (313 loc) 9.93 kB
/** * Type definitions for the NeuroLink TaskManager system. * * TaskManager provides scheduled and self-running task capabilities, * enabling AI agents to execute prompts on cron, interval, or one-shot schedules. */ import type { Cron } from "croner"; import type { createClient } from "redis"; import type { MemoryMetricConfig, MetricConfig } from "./autoresearch.js"; import type { ThinkingLevel } from "./config.js"; /** * Discriminator for standard vs autoresearch tasks. * - "standard": Normal prompt-based task (default) * - "autoresearch": Autonomous experiment loop task */ export type ScheduledTaskType = "standard" | "autoresearch"; /** * Configuration for autoresearch tasks. * Embedded in TaskDefinition/Task when type === "autoresearch". */ export type AutoresearchTaskConfig = { repoPath: string; mutablePaths: string[]; runCommand: string; metric: MetricConfig; immutablePaths?: string[]; timeoutMs?: number; maxExperiments?: number; provider?: string; model?: string; thinkingLevel?: ThinkingLevel; maxBudgetUsd?: number; programPath?: string; resultsPath?: string; statePath?: string; logPath?: string; branchPrefix?: string; memoryMetric?: MemoryMetricConfig; }; export type TaskScheduleType = "cron" | "interval" | "once"; export type CronSchedule = { type: "cron"; /** Standard 5-field cron expression, e.g. "0 9 * * *" */ expression: string; /** IANA timezone, e.g. "America/New_York" */ timezone?: string; }; export type IntervalSchedule = { type: "interval"; /** Interval in milliseconds */ every: number; }; export type OnceSchedule = { type: "once"; /** ISO 8601 timestamp or Date object */ at: Date | string; }; export type TaskSchedule = CronSchedule | IntervalSchedule | OnceSchedule; /** * - "isolated": Each run gets a fresh context. No memory of previous runs. * - "continuation": Conversation history is preserved across runs. */ export type TaskExecutionMode = "isolated" | "continuation"; export type TaskStatus = "pending" | "active" | "paused" | "completed" | "failed" | "cancelled"; export type TaskDefinition = { name: string; prompt: string; schedule: TaskSchedule; mode?: TaskExecutionMode; /** Task type discriminator. Default: "standard" */ type?: ScheduledTaskType; /** Autoresearch config (required when type === "autoresearch") */ autoresearch?: AutoresearchTaskConfig; provider?: string; model?: string; thinkingLevel?: ThinkingLevel; systemPrompt?: string; /** Enable/disable tools for this task. Default: true */ tools?: boolean; maxTokens?: number; temperature?: number; /** Max number of executions. Omit for unlimited. */ maxRuns?: number; /** Per-run timeout in ms. Default: 120000 */ timeout?: number; retry?: { /** Default: 3 */ maxAttempts?: number; /** Default: [30000, 60000, 300000] */ backoffMs?: number[]; }; onSuccess?: (result: TaskRunResult) => void | Promise<void>; onError?: (error: TaskRunError) => void | Promise<void>; /** Called when task reaches a terminal state (completed, failed, cancelled) */ onComplete?: (task: Task) => void | Promise<void>; metadata?: Record<string, unknown>; }; export type Task = { id: string; name: string; prompt: string; schedule: TaskSchedule; mode: TaskExecutionMode; /** Task type discriminator. Default: "standard" */ type: ScheduledTaskType; status: TaskStatus; /** Autoresearch config (present when type === "autoresearch") */ autoresearch?: AutoresearchTaskConfig; provider?: string; model?: string; thinkingLevel?: ThinkingLevel; systemPrompt?: string; tools: boolean; maxTokens?: number; temperature?: number; maxRuns?: number; timeout: number; retry: { maxAttempts: number; backoffMs: number[]; }; runCount: number; lastRunAt?: string; nextRunAt?: string; createdAt: string; updatedAt: string; /** Conversation session ID for continuation mode */ sessionId?: string; metadata?: Record<string, unknown>; }; /** Shape of the tasks.json file used by FileTaskStore */ export type TasksFile = { version: number; tasks: Record<string, Task>; }; export type TaskRunResult = { taskId: string; runId: string; status: "success" | "error"; /** AI response text */ output?: string; toolCalls?: Array<{ name: string; input: unknown; output: unknown; }>; tokensUsed?: { input: number; output: number; }; durationMs: number; /** ISO 8601 */ timestamp: string; error?: string; }; export type TaskRunError = { taskId: string; runId: string; error: string; attempt: number; maxAttempts: number; willRetry: boolean; /** ISO 8601 */ timestamp: string; }; /** * Abstracts task persistence. Auto-selected based on backend: * - BullMQ → RedisTaskStore * - NodeTimeout → FileTaskStore */ export type TaskStore = { readonly type: "redis" | "file"; initialize(): Promise<void>; shutdown(): Promise<void>; save(task: Task): Promise<void>; get(taskId: string): Promise<Task | null>; list(filter?: { status?: TaskStatus; }): Promise<Task[]>; update(taskId: string, updates: Partial<Task>): Promise<Task>; delete(taskId: string): Promise<void>; appendRun(taskId: string, run: TaskRunResult): Promise<void>; getRuns(taskId: string, options?: { limit?: number; status?: string; }): Promise<TaskRunResult[]>; appendHistory(taskId: string, messages: ConversationEntry[]): Promise<void>; getHistory(taskId: string): Promise<ConversationEntry[]>; clearHistory(taskId: string): Promise<void>; }; export type ConversationEntry = { role: "user" | "assistant"; content: string; timestamp: string; }; export type TaskExecutorFn = (task: Task) => Promise<TaskRunResult>; /** * Abstracts the scheduling/looping mechanism. * Implementations: BullMQ (production), NodeTimeout (development). */ export type TaskBackend = { readonly name: string; initialize(): Promise<void>; shutdown(): Promise<void>; /** Schedule a task for execution */ schedule(task: Task, executor: TaskExecutorFn): Promise<void>; /** Cancel a scheduled task */ cancel(taskId: string): Promise<void>; /** Pause a task's schedule */ pause(taskId: string): Promise<void>; /** Resume a paused task */ resume(taskId: string): Promise<void>; /** Check if backend is operational */ isHealthy(): Promise<boolean>; }; /** Redis client type used by RedisTaskStore */ export type RedisClient = ReturnType<typeof createClient>; /** Minimal interface for the NeuroLink SDK methods needed by TaskExecutor */ export type NeuroLinkExecutable = { generate(optionsOrPrompt: unknown): Promise<{ content: string; toolExecutions?: Array<{ name: string; input: unknown; output: unknown; }>; usage?: { input?: number; output?: number; }; }>; }; /** Internal scheduling entry used by NodeTimeoutBackend */ export type ScheduledEntry = { taskId: string; executor: TaskExecutorFn; task: Task; cronJob?: Cron; intervalId?: ReturnType<typeof setInterval>; timeoutId?: ReturnType<typeof setTimeout>; }; export type TaskBackendName = "bullmq" | "node-timeout"; export type TaskBackendFactoryFn = (config: TaskManagerConfig) => Promise<TaskBackend>; export type TaskRetentionConfig = { /** Auto-delete completed tasks after N ms. Default: 30 days */ completedTTL?: number; /** Auto-delete failed tasks after N ms. Default: 7 days */ failedTTL?: number; /** Auto-delete cancelled tasks after N ms. Default: 7 days */ cancelledTTL?: number; /** Auto-expire individual run log entries after N ms. Default: 30 days */ runLogTTL?: number; }; export type TaskManagerConfig = { /** Default: true */ enabled?: boolean; /** Default: "bullmq" */ backend?: TaskBackendName; redis?: { host?: string; port?: number; password?: string; db?: number; /** Alternative: full Redis URL */ url?: string; }; /** Default: ".neurolink/tasks/tasks.json" */ storePath?: string; /** Default: ".neurolink/tasks/runs/" */ logsPath?: string; /** Maximum number of tasks that can exist at once. Default: 100 */ maxTasks?: number; /** Default: 5 */ maxConcurrentRuns?: number; /** Max run log entries per task. Default: 2000 */ maxRunLogs?: number; /** Max continuation history entries per task. Default: 200 (100 exchanges) */ maxHistoryEntries?: number; taskRetention?: TaskRetentionConfig; }; export declare const TASK_DEFAULTS: { readonly enabled: true; readonly maxTasks: 100; readonly backend: TaskBackendName; readonly mode: TaskExecutionMode; readonly timeout: 120000; readonly maxConcurrentRuns: 5; readonly maxRunLogs: 2000; readonly maxHistoryEntries: 200; readonly tools: true; readonly retry: { readonly maxAttempts: 3; readonly backoffMs: readonly [30000, 60000, 300000]; }; readonly storePath: ".neurolink/tasks/tasks.json"; readonly logsPath: ".neurolink/tasks/runs/"; readonly redis: { readonly host: "localhost"; readonly port: 6379; }; readonly retention: { readonly completedTTL: number; readonly failedTTL: number; readonly cancelledTTL: number; readonly runLogTTL: number; }; }; /** State persisted by the CLI task worker daemon */ export type WorkerState = { pid: number; startedAt: string; logFile: string; };