187 lines
4.0 KiB
JavaScript
187 lines
4.0 KiB
JavaScript
/**
|
|
* AI Task Registry
|
|
*
|
|
* Simple registry pattern for AI tasks. Each task has:
|
|
* - id: Unique identifier
|
|
* - run: Async function that executes the task
|
|
*
|
|
* This allows adding new AI capabilities without modifying core code.
|
|
*/
|
|
|
|
const { createNameValidationTask, TASK_ID: NAME_TASK_ID } = require('./nameValidationTask');
|
|
const { createDescriptionValidationTask, TASK_ID: DESC_TASK_ID } = require('./descriptionValidationTask');
|
|
const { createSanityCheckTask, TASK_ID: SANITY_TASK_ID } = require('./sanityCheckTask');
|
|
|
|
/**
|
|
* Task IDs - frozen constants for type safety
|
|
*/
|
|
const TASK_IDS = Object.freeze({
|
|
// Inline validation (triggered on field blur)
|
|
VALIDATE_NAME: NAME_TASK_ID,
|
|
VALIDATE_DESCRIPTION: DESC_TASK_ID,
|
|
|
|
// Batch operations (triggered on user action)
|
|
SANITY_CHECK: SANITY_TASK_ID
|
|
});
|
|
|
|
/**
|
|
* Task Registry
|
|
*/
|
|
class TaskRegistry {
|
|
constructor() {
|
|
this.tasks = new Map();
|
|
}
|
|
|
|
/**
|
|
* Register a task
|
|
* @param {Object} task
|
|
* @param {string} task.id - Unique task identifier
|
|
* @param {Function} task.run - Async function: (payload) => result
|
|
* @param {string} [task.description] - Human-readable description
|
|
*/
|
|
register(task) {
|
|
if (!task?.id) {
|
|
throw new Error('Task must have an id');
|
|
}
|
|
if (typeof task.run !== 'function') {
|
|
throw new Error(`Task ${task.id} must have a run function`);
|
|
}
|
|
if (this.tasks.has(task.id)) {
|
|
throw new Error(`Task ${task.id} is already registered`);
|
|
}
|
|
|
|
this.tasks.set(task.id, task);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get a task by ID
|
|
* @param {string} taskId
|
|
* @returns {Object|null}
|
|
*/
|
|
get(taskId) {
|
|
return this.tasks.get(taskId) || null;
|
|
}
|
|
|
|
/**
|
|
* Check if a task exists
|
|
* @param {string} taskId
|
|
* @returns {boolean}
|
|
*/
|
|
has(taskId) {
|
|
return this.tasks.has(taskId);
|
|
}
|
|
|
|
/**
|
|
* Run a task by ID
|
|
* @param {string} taskId
|
|
* @param {Object} payload - Task-specific input
|
|
* @returns {Promise<Object>} Task result
|
|
*/
|
|
async runTask(taskId, payload = {}) {
|
|
const task = this.get(taskId);
|
|
if (!task) {
|
|
throw new Error(`Unknown task: ${taskId}`);
|
|
}
|
|
|
|
try {
|
|
const result = await task.run(payload);
|
|
return {
|
|
success: true,
|
|
taskId,
|
|
...result
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
taskId,
|
|
error: error.message,
|
|
code: error.code
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* List all registered task IDs
|
|
* @returns {string[]}
|
|
*/
|
|
list() {
|
|
return Array.from(this.tasks.keys());
|
|
}
|
|
|
|
/**
|
|
* Get count of registered tasks
|
|
* @returns {number}
|
|
*/
|
|
size() {
|
|
return this.tasks.size;
|
|
}
|
|
}
|
|
|
|
// Singleton instance
|
|
let registry = null;
|
|
|
|
/**
|
|
* Get or create the task registry
|
|
* @returns {TaskRegistry}
|
|
*/
|
|
function getRegistry() {
|
|
if (!registry) {
|
|
registry = new TaskRegistry();
|
|
}
|
|
return registry;
|
|
}
|
|
|
|
/**
|
|
* Reset the registry (mainly for testing)
|
|
*/
|
|
function resetRegistry() {
|
|
registry = null;
|
|
}
|
|
|
|
/**
|
|
* Register all validation tasks with the registry
|
|
* Call this during initialization after the registry is created
|
|
*
|
|
* @param {Object} [logger] - Optional logger
|
|
*/
|
|
function registerAllTasks(logger = console) {
|
|
const reg = getRegistry();
|
|
|
|
// Register name validation
|
|
if (!reg.has(TASK_IDS.VALIDATE_NAME)) {
|
|
reg.register(createNameValidationTask());
|
|
logger.info(`[Tasks] Registered: ${TASK_IDS.VALIDATE_NAME}`);
|
|
}
|
|
|
|
// Register description validation
|
|
if (!reg.has(TASK_IDS.VALIDATE_DESCRIPTION)) {
|
|
reg.register(createDescriptionValidationTask());
|
|
logger.info(`[Tasks] Registered: ${TASK_IDS.VALIDATE_DESCRIPTION}`);
|
|
}
|
|
|
|
// Register sanity check
|
|
if (!reg.has(TASK_IDS.SANITY_CHECK)) {
|
|
reg.register(createSanityCheckTask());
|
|
logger.info(`[Tasks] Registered: ${TASK_IDS.SANITY_CHECK}`);
|
|
}
|
|
|
|
return reg;
|
|
}
|
|
|
|
module.exports = {
|
|
// Constants
|
|
TASK_IDS,
|
|
|
|
// Registry
|
|
TaskRegistry,
|
|
getRegistry,
|
|
resetRegistry,
|
|
registerAllTasks,
|
|
|
|
// Task factories (for custom registration)
|
|
createNameValidationTask,
|
|
createDescriptionValidationTask,
|
|
createSanityCheckTask
|
|
};
|