Update tasks

Updating the status of tasks in Lattice using the Lattice SDK

In Lattice, a task status represents each stage of the task lifecycle. When an agent receives a task, it calls the following API to update a task in Lattice:

  • UpdateStatus: Used to report real-time status updates to Lattice as the agent makes progress through a task.

Before you begin

  • To publish taskable entities, and subscribe to tasks, set up your Lattice environment.
  • Familiarize yourself with entities and different entity types.

Start performing a task

After an agent has identified a task to perform and begins to make progress towards its objective, it communicates back to Lattice using the UpdateTaskStatus to cycle through various states of a task lifecycle.

To update the status of a task, do the following:

1

Listen for tasks

Use the ListenAsAgent operation. In this example, the agent listens for assigned tasks, then updates the task status, incrementing the StatusVersion of the task.

Replace AGENT_ID with the ID of the agent you want to task. If you are developing on Sandboxes, replace this with the following simulated asset: Demo-Sim-Asset1:

1from anduril import Lattice, EntityIdsSelector, TaskStatus, Principal, System
2import asyncio, os, sys
3
4lattice_endpoint = os.getenv('LATTICE_ENDPOINT')
5environment_token = os.getenv('ENVIRONMENT_TOKEN')
6
7# Remove sandboxes_token from the following statements if you are not developing on Sandboxes.
8sandboxes_token = os.getenv('SANDBOXES_TOKEN')
9if not environment_token or not lattice_endpoint or not sandboxes_token:
10 print("Missing required environment variables.")
11 sys.exit(1)
12
13client = Lattice(
14 base_url=f"https://{lattice_endpoint}",
15 token=environment_token,
16 # Remove the following header if you are not developing on Sandboxes.
17 headers={ "anduril-sandbox-authorization": f"Bearer {sandboxes_token}" }
18)
19async def listen_as_agent(agent_entity_id):
20 try:
21 requests = client.tasks.listen_as_agent(
22 agent_selector=EntityIdsSelector(
23 entity_ids=[agent_entity_id]
24 )
25 )
26 return requests
27 except Exception as error:
28 print(f"Encountered the following error while listening for tasks: {error}")
29
30async def start_task(task_id, task_status_version, agent_entity_id):
31 try:
32 task_status_version += 1
33 response = await client.tasks.update_task_status(
34 task_id=task_id,
35 status_version=task_status_version,
36 new_status=TaskStatus(
37 status="STATUS_EXECUTING"
38 ),
39 author=Principal(
40 system=System(
41 entity_id=agent_entity_id
42 )
43 )
44 )
45 return response
46 except Exception as error:
47 print(f"Encountered the following error while starting task: {error}")
48
49async def main(entity_id):
50 while True:
51 try:
52 print(f"Listening for tasks for entity: {entity_id}...")
53 request = await listen_as_agent(entity_id)
54 if request.execute_request:
55 # Parse task-specific information.
56 task_id = request.execute_request.task.version.task_id
57 task_status_version = request.execute_request.task.version.status_version
58
59 print(f"Starting task {task_id}, version {task_status_version}.")
60 result = start_task(task_id, task_status_version, entity_id)
61 print (f"Started task with status version: {result.version.status_version}.")
62
63 elif request.complete_request:
64 print(f"Completing task: {request.complete_request.task_id}")
65 elif request.cancel_request:
66 print(f"Cancelling task:, {request.cancel_request.task_id}")
67 except Exception as error:
68 print("Encountered the following error while processing task:", error)
69
70if __name__ == "__main__":
71 raise SystemExit(asyncio.run(main(entity_id="ENTITY_ID")))
2

Assign a task using the UI

To assign a task, do the following:

  1. Open your environment’s Lattice UI, and choose an asset from the Assets panel. On Sandboxes, choose Demo-Sim-Asset1:
  2. From the entity pane, choose Task, then select a task, for example, Follow:
    Shows the drop down menu where you can see the available tasks for the entity.
  3. From the Task Details panel on the right hand side, select a target then choose Execute Task:
    Shows the drop down menu where you can see available targets for the task.
3

Verify the task status

If successful, you see the following output in your local development console:

$Starting task <task-id>, version 1.
>Started task with status version: 2.

The agent has successfully updated the tasks status and incremented the task status version.

Task lifecycle

In Lattice tasks move through the following states:

1

STATUS_SENT

The agent receives a task with STATUS_SENT:

1"task": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 1
6 },
7 "status": {
8 "status": "STATUS_SENT"
9 }
10}
2

STATUS_MACHINE_RECEIPT

The agent then responds back with status STATUS_MACHINE_RECEIPT, indicating that the task has been received, and incrementing statusVersion accordingly:

1"statusUpdate": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 2
6 },
7 "status": {
8 "status": "STATUS_MACHINE_RECEIPT"
9 }
10}
3

STATUS_ACK

When the agent is ready to acknowledge the task, it does so using STATUS_ACK, and again increments statusVersion:

1"statusUpdate": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 3
6 },
7 "status": {
8 "status": "STATUS_ACK"
9 }
10}
4

STATUS_WILCO

The agent confirms it intends to execute the task using STATUS_WILCO:

1"statusUpdate": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 4
6 },
7 "status": {
8 "status": "STATUS_WILCO"
9 }
10}
5

STATUS_EXECUTING

As the agent begins to actively execute the task, it indicates this by reporting STATUS_EXECUTING back to Lattice:

1"statusUpdate": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 5
6 },
7 "status": {
8 "status": "STATUS_EXECUTING"
9 }
10}
6

STATUS_DONE_OK

Finally, when the agent reaches a terminal state and completes the task successfully, it reports STATUS_DONE_OK. This might result from operator-initiated requests for task completion:

1"statusUpdate": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 6
6 },
7 "status": {
8 "status": "STATUS_DONE_OK"
9 }
10}
7

STATUS_DONE_NOT_OK

If the agent reaches a terminal state but does not complete the task successfully, it reports STATUS_DONE_NOT_OK. This might result from operator-initiated requests for task completion or cancellation. The agent should include a descriptive TaskError when reporting STATUS_DONE_NOT_OK:

1"statusUpdate": {
2 "version": {
3 "taskId": "my-task",
4 "definitionVersion": 1,
5 "statusVersion": 7
6 },
7 "status": {
8 "status": "DONE_NOT_OK",
9 "taskError": {
10 "code": "ERROR_CODE_FAILED",
11 "message": "The asset failed task execution due to an internal error.",
12 }
13 }
14}

In this example, the message indicates that the agent encountered an internal error during task execution. You can add more descriptive errors to help the operator troubleshoot the issue accordingly.

The STATUS_DONE_OK and STATUS_DONE_NOT_OK statuses are considered terminal states. Once a task’s reaches either state, it’s complete and cannot be updated.

What’s next

  • To learn more about tasks, see Task an asset in in the Lattice SDK sample applications guide.