MCPcopy Create free account
hub / github.com/Noumena-Network/code / claimTask

Function claimTask

src/utils/tasks.ts:542–613  ·  view source on GitHub ↗
(
  taskListId: string,
  taskId: string,
  claimantAgentId: string,
  options: ClaimTaskOptions = {},
)

Source from the content-addressed store, hash-verified

540 * if the agent owns any other open tasks before claiming.
541 */
542export async function claimTask(
543 taskListId: string,
544 taskId: string,
545 claimantAgentId: string,
546 options: ClaimTaskOptions = {},
547): Promise<ClaimTaskResult> {
548 const taskPath = getTaskPath(taskListId, taskId)
549
550 // Check existence before locking — proper-lockfile.lock throws if the
551 // target file doesn't exist, and we want a clean task_not_found result.
552 const taskBeforeLock = await getTask(taskListId, taskId)
553 if (!taskBeforeLock) {
554 return { success: false, reason: 'task_not_found' }
555 }
556
557 // If we need to check agent busy status, use task-list-level lock
558 // to prevent TOCTOU race conditions
559 if (options.checkAgentBusy) {
560 return claimTaskWithBusyCheck(taskListId, taskId, claimantAgentId)
561 }
562
563 // Otherwise, use task-level lock (original behavior)
564 let release: (() => Promise<void>) | undefined
565 try {
566 // Acquire exclusive lock on the task file
567 release = await lockfile.lock(taskPath, LOCK_OPTIONS)
568
569 // Read current task state
570 const task = await getTask(taskListId, taskId)
571 if (!task) {
572 return { success: false, reason: 'task_not_found' }
573 }
574
575 // Check if already claimed by another agent
576 if (task.owner && task.owner !== claimantAgentId) {
577 return { success: false, reason: 'already_claimed', task }
578 }
579
580 // Check if already resolved
581 if (task.status === 'completed') {
582 return { success: false, reason: 'already_resolved', task }
583 }
584
585 // Check for unresolved blockers (open or in_progress tasks block)
586 const allTasks = await listTasks(taskListId)
587 const unresolvedTaskIds = new Set(
588 allTasks.filter(t => t.status !== 'completed').map(t => t.id),
589 )
590 const blockedByTasks = task.blockedBy.filter(id =>
591 unresolvedTaskIds.has(id),
592 )
593 if (blockedByTasks.length > 0) {
594 return { success: false, reason: 'blocked', task, blockedByTasks }
595 }
596
597 // Claim the task (already holding taskPath lock — use unsafe variant)
598 const updated = await updateTaskUnsafe(taskListId, taskId, {
599 owner: claimantAgentId,

Callers 2

tryClaimNextTaskFunction · 0.85
useTaskListWatcherFunction · 0.85

Calls 10

getTaskPathFunction · 0.85
getTaskFunction · 0.85
claimTaskWithBusyCheckFunction · 0.85
listTasksFunction · 0.85
updateTaskUnsafeFunction · 0.85
logForDebuggingFunction · 0.70
errorMessageFunction · 0.70
logErrorFunction · 0.70
releaseFunction · 0.50
hasMethod · 0.45

Tested by

no test coverage detected