• Exacta Maestro™ Integration Design
  • User Guide
  • GraphQL User Guide
  • FAQ
  • Technical
  • Terminology
Show / Hide Table of Contents
  • GraphQL User Guide
    • Introduction
    • Authentication
    • Schema Organization
    • Building GraphQL Queries
    • Executing GraphQL Queries
    • Executing GraphQL Queries (Legacy)
    • Agent Management
    • Task Management

Task Management

This guide shows how to create, edit, and delete task groups, tasks, and missions. Tasks are Exacta Maestro™'s basic unit of work. By creating a task, you are scheduling work for autonomous vehicles in your facility. Exacta Maestro™ can intelligently assign tasks to the best agent for the job. You can also require a task be assigned to a specific agent.

Task groups are loose collections of tasks which are released for assignment together. Other systems may refer to this structure as a wave. Tasks in a task group are not eligible for assignment until the task group is activated. This allows users to delay assignment until Exacta Maestro™ has a complete picture of the priorities and due dates of the tasks to assign.

New Task Group

This sample shows how to create a task group through the GraphQL interface. The task group will start in a 'New' status. Tasks created against this task group will not be eligible for assignment until the task group is activated.

# Query

mutation newTaskGroup($taskGroupName:String!) {
  taskAssignmentMutation {
    newTaskGroup(request: { name: $taskGroupName }) {
      isSuccess
      error {
        key
        collectionName
        message
      }
      value {
        id
        name
        dateCreated
        taskGroupState
      }
    }
  }
}

# Variables

{
  "taskGroupName":"My Task Group"
}

Set Task Group Active

This sample shows how to activate a task group so that tasks created against it become eligible for assignment.

# Query

mutation setTaskGroupActive($taskGroupName:String!) {
  taskAssignmentMutation {
    setTaskGroupActive(taskGroupName:$taskGroupName) {
      isSuccess
      error
    }
  }
}

# Variables

{
   "taskGroupName": "My Task Group"
}

Get Task Groups

Get TaskGroup by Name

This sample shows how to fetch a single task group by name. You can optionally retrieve tasks belonging to the group with this query. To return data about the task group only, omit the tasks field selection from the sample query.

# Query

query getTaskGroup($taskGroupName: String!) {
  taskAssignmentQuery {
    getTaskGroupByName(taskGroupName: $taskGroupName) {
      isSuccess
      error
      value {
        name
        taskGroupState
        id
        dateCreated
        taskGroupMetrics {
          numberOfTasks
          numberOfAssignedTasks
          numberOfDispatchedTasks
          numberOfCancelledTasks
          numberOfCompletedTasks
          numberOfFaultedTasks
        }
        
        # omit tasks to get task group data only
        tasks {
          isSuccess
          error
          value {
            name
            taskType
            agentId
            assignmentStatus
            executionStatus
            taskStateChange {
              dateStamp
              taskMutationType
              message
            }        
            # other task fields...  
          }          
        }
      }
    }
  }
}

# Variables

{
  "taskGroupName": "My Task Group"
}

Get TaskGroups Query

This sample shows how to query for multiple task groups using various criteria such as state or date created filters. All criteria shown can be combined or omitted as needed.

When filtering by task group states, provide an array of states to include. The following states are valid:

  • New = 0
  • Active = 100
  • Paused = 200
  • Completed = 300
  • Cancelled = 400

When filtering by date, provide a string in ISO 8601 datetime format.

# Query

query getTaskGroups($input: TaskGroupQueryInput!) {
  taskAssignmentQuery {
    getTaskGroups(queryTaskGroupInput: $input) {
      id
      name
      dateCreated
      taskGroupState
      taskGroupMetrics {
        numberOfTasks
        numberOfAssignedTasks
        numberOfDispatchedTasks
        numberOfCancelledTasks
        numberOfCompletedTasks
        numberOfFaultedTasks
      }
    }
  }
}

# Variables

{
  "input": {
    "taskGroupStates": [0, 100],
    "minDateCreated": "2019-11-12T00:00:00Z",
    "maxDateCreated": "2019-11-13T00:00:00Z"
  }
}

Create Tasks

Exacta Maestro™ supports a few different task payload types, as well as a few different task relationships. Within AgentHub, each AgentType can be configured to handle one or more task types. However, depending on the agent integration, not all agent services are actually capable of handling all types of task payloads.

TaskType Description Payload
TransferTask Move a container from a source location to a destination location Container, SourceLocationQuery, DestinationLocationQuery
Mission Perform the specified child tasks sequentially ChildTaskNames
PalletPickTask Pick a container from a location LocationId
PalletPlaceTask Drop a container to a location LocationId
ProductPickTask Pick a specified number of products from a location LocationId, Quantity

When a task is created, the loose CriteriaPayload ("TaskPayload") is defined. Then during the assignment process the task's InstructionPayload is resolved. For example, the criteria payload for a TransferTask may use a regex to specify that a container should get dropped into a specific aisle, but the final location doesn't get resolved until the task is getting assigned to an agent.

New Transfer Task

The most common type of task within Exacta Maestro™ is the TransferTask, which can be PickOnly (destination null), DropOnly (source null), or PickAndDrop.

Furthermore, TransferTasks can be standalone (executed by a single agent), a host macro task (container movement broken into multiple child tasks for multiple different agents), a macro child task (1 part of moving a container through the warehouse), or a mission child task (one of many things that an agent must do sequentially).

# Query

mutation newTransferTask($input:TransferTaskInputModelInput!) {
  taskAssignmentMutation {
    newTransferTask(request:$input) {
      isSuccess
      error {
        key
        collectionName
        message
      }
      value {
        name
      }
    }
  }
}

# Variables

{
   "input": {
    "name": "Child Task 1",
    "taskGroupName": "My Task Group",
    "priority": 1,
    "dueDate": "2019-08-14T12:00:00.000Z",
    "container": {
      "id": "Test Container 1",
      "dimensions": { x: 1, y: 2, z: 3 },
      "type": "1",
      "weight": 4.56,
      "customDetails": [
        { "key": "a", "value": "value a" },
        { "key": "b", "value": "value b" },
        { "key": "c", "value": "value c" },
      ]
    },
    "sourceLocationQuery": {
      "locationId": "host system location id", # Use if target location is known
      "locationPattern": "regex pattern targeting Exacta Maestro™ system location ids", # Use to prompt Exacta Maestro™ to select from one of several possible locations
      "containerId": "host system container id", # Use to select location based on container id
      "excludedLocations": [] # Use to exclude locations from consideration if using locationPattern
    },
    "destinationLocationQuery": {
      "locationId": "host system location id",
      "locationPattern": "regex pattern targeting Exacta Maestro™ system location ids",
      "containerId": "host system container id",
      "excludedLocations": []
    },
    "predecessorTasks": []
  }
}

New Mission

Missions are used to ensure that a single agent handles multiple different child tasks sequentially. Not all agent integrations support missions, while some agent integrations require them. The mission can be created before or after the creation of the individual child tasks. The child tasks can be of any task payload type other than Mission (missions cannot be nested).

The mission itself should not have a MissionName specified, the MissionName should only contain a value on the individual child tasks.

Mission Creation Process

# Query

mutation newMission($input:MissionTaskInputModelInput!) {
  taskAssignmentMutation {
    newMission(request:$input) {
      isSuccess
      error {
        key
        collectionName
        message
      }
      value {
        name
      }
    }
  }
}

# Variables

{
   "input": {
    "name": "Mission 1",
    "taskGroupName": "My Task Group",
    "priority": 1,
    "dueDate": "2019-08-14T12:00:00.000Z",
    "taskNames": [
      "Child Task 1",
      "Child Task 2",
      "Child Task 3",
      "Child Task 4"
    ]
  }
}

New Pallet Pick Task

# Query

mutation newPalletPickTask($input:PalletPickTaskInputModelInput!) {
  taskAssignmentMutation {
    newPalletPickTask(request:$input) {
      isSuccess
      error {
        key
        collectionName
        message
      }
      value {
        name
      }
    }
  }
}

# Variables

{
   "input": {
    "name": "Child Task 2",
    "missionName": "Mission 1",
    "taskGroupName": "My Task Group",
    "priority": 1,
    "dueDate": "2019-08-14T12:00:00.000Z",
    "locationId": "host system location id"
  }
}

New Pallet Place Task

# Query

mutation newPalletPlaceTask($input:PalletPlaceTaskInput!) {
  taskAssignmentMutation {
    newPalletPlaceTask(request:$input) {
      isSuccess
      error {
        key
        collectionName
        message
      }
      value {
        name
      }
    }
  }
}

# Variables

{
   "input": {
    "name": "Child Task 3",
    "missionName": "Mission 1",
    "taskGroupName": "My Task Group",
    "priority": 1,
    "dueDate": "2019-08-14T12:00:00.000Z",
    "locationId": "host system location id"
  }
}

New Product Pick Task

# Query

mutation newProductPickTask($input:ProductPickTaskInputModelInput!) {
  taskAssignmentMutation {
    newProductPickTask(request:$input) {
      isSuccess
      error {
        key
        collectionName
        message
      }
      value {
        name
      }
    }
  }
}


# Variables

{
   "input": {
    "name": "Child Task 4",
    "missionName": "Mission 1",
    "taskGroupName": "My Task Group",
    "priority": 1,
    "dueDate": "2019-08-14T12:00:00.000Z",
    "quantity": 10,
    "locationId": "host system location id"
  }
}

Get Tasks

Tasks in Exacta Maestro™ can have different types of payloads, as described in the Create Tasks section. To resolve these different types of CriteriaPayload and InstructionPayload, the GraphQL schema uses "Fragments".

Get Task by Name

query getTask {
  taskAssignmentQuery {
    getTaskByName(taskName: "TG1 T1") {
      isSuccess
      error
      value {
        name
        taskType
        __typename
        assignmentStatus
        executionStatus
        agentId
        requiredAgentId
        agentTypeId
        endReason
        endingUserId
        creationDate
        dispatchDate
        dueDate
        ... on TransferTask {
          criteriaPayload {
            sourceLocationQuery {
              containerId
              locationId
              locationPatterns
              excludedLocations
            }
            destinationLocationQuery {
              containerId
              locationId
              locationPatterns
              excludedLocations
            }
            container {
              id
              type
              dimensions {
                x
                y
                z
              }
              weight
              customDetails {
                key
                value
              }
            }
            agentPayloadPosition {
              positionId
              payloadPositionIdConstraints
            }
          }
          instructionPayload {
            sourceLocationId
            destinationLocationId
            destinationReservationToken
            container {
              id
              type
              dimensions {
                x
                y
                z
              }
              weight
              customDetails {
                key
                value
              }
            }
          }
        }
        ... on MissionTask {
          criteriaPayload {
            taskNames
          }
          instructionPayload {
            childTasks {
              name
              type
            }
            taskTypes
          }
        }
        ... on ProductPickTask {
          criteriaPayload {
            locationId
            quantity
          }
          instructionPayload {
            locationId
            quantity
          }
        }
        ... on PalletPickTask {
          criteriaPayload {
            locationId
          }
          instructionPayload {
            locationId
          }
        }
        ... on PalletPlaceTask {
          criteriaPayload {
            locationId
          }
          instructionPayload {
            locationId
          }
        }
      }
    }
  }
}

Get Tasks Paged

The getTasks endpoint is used to get a page of tasks at a time. A request parameter can also be used to filter while tasks are returned. Note that this example only resolves the task name, but it could request all of the fields and fragments as shown in the previous example.

query getTasks {
  taskAssignmentQuery {
    getTasks(
      first: 20
      last: null
      before: null
      pageRequest: {
        previousItems: 0
        nextItems: 20
        beforeCursor: null
        afterCursor: null
      }
    ) {
      __typename
      nodes {
        name
      }
    }
  }
}

Update Task

Limited support is available for updating the properties of a task, including the properties dueDate, priority, requiredAgentId, and OnHold. Once a task is assigned, no properties can be changed.

# Query

mutation updateTasksOperation($input:UpdateTaskBatchCommandInput!) {
  taskAssignmentMutation {
    updateTasks(request:$input) {
      errors {
        results {
          id
          isSuccess
          error
        }
      }
      updatedTaskNames
    }
  }
}

# Variables

{
  "input": {
    "taskGroupName": "Task Group Name",
    "updateTaskCommands": [
      {
        "name": "Task Name",
        "dueDate": "2019-08-14T12:00:00.000Z",
        "priority": 1,
        "onHold": false,
        "requiredAgentId": "Agent 2"
      }
    ]
  }
}

Force End Task

Host systems may request that a task gets immediately Completed, Cancelled, or Faulted. When the call is made the request is queued for asynchronous processing. Therefore, a success result only indicates that the request will be processed, not that the task was successfully ended.

CustomDetails can be passed with the request, used to control how the system updates in response to the ended task. For example, the keys InventoryPicked and InventoryPlaced can be used to control whether or not the inventory updates should occur.

Complete Task

Use this to forcefully end an agent's task in a successful state. This is useful when the agent faulted and required manual intervention to complete its task. Issue the following query to start the process, then monitor the task's status. If the task ends before completion is processed, the operation will fail silently.

# Query

mutation beginCompleteTaskOperation($input:BeginCompleteTaskCommandInput!) {
  taskAssignmentMutation {
    beginCompleteTask(request: $input) {
      isSuccess
      error
    }
  }
}

# Variables

{
  "input": {
    "taskName": "Task Name",
    "taskGroupName": "Task group name",
    "endReason": "Test",
    "endingUserId": "Admin"
  }
}

Cancel Task

Issue the following query to start the process of cancelling the execution of a task, then monitor the task's status. If the task ends before cancellation is processed, or if the assigned agent doesn't support cancellation, the operation will fail silently.

# Query

mutation beginCancelTaskOperation($input:BeginCancelTaskCommandInput!) {
  taskAssignmentMutation {
    beginCancelTask(request: $input) {
      isSuccess
      error
    }
  }
}

# Variables

{
  "input": {
    "taskName": "Task Name",
    "taskGroupName": "Task group name"
    "endReason": "Test",
    "endingUserId": "Admin",
    "customDetails": [
      { "key": "InventoryPicked", "value": "true" },
      { "key": "InventoryPlaced", "value": "false" }
    ]
  }
}

Fault Task

Use this to forcefully end an agent's task in a faulted state. This is useful when the task was invalid or otherwise could not be completed. Issue the following query to start the process, then monitor the task's status. If the task ends before faulting is processed, the operation will fail silently.

# Query

mutation beginFaultTaskOperation($input:BeginFaultTaskCommandInput!) {
  taskAssignmentMutation {
    beginFaultTask(request: $input) {
      isSuccess
      error
    }
  }
}

# Variables

{
  "input": {
    "taskName": "Task Name",
    "taskGroupName": "Task group name",
    "endReason": "Test",
    "endingUserId": "Admin"
  }
}

In This Article