Skip to content

Todo List Demo

This demo shows how to create a simple task management system with VOIX. Users can add, complete, and delete tasks using natural language.

How It Works

The todo list provides tools for common task operations and maintains context about the current tasks.

Code

html
<tool name="add_task" description="Add a new task to the list" return>
  <prop name="title" type="string" required></prop>
  <prop name="priority" type="string" description="high, medium, or low"></prop>
</tool>

<tool name="complete_task" description="Mark a task as completed">
  <prop
    name="taskId"
    type="string"
    description="ID of the task to complete"
    required
  ></prop>
</tool>

<tool name="delete_task" description="Delete a task from the list">
  <prop
    name="taskId"
    type="string"
    description="ID of the task to delete"
    required
  ></prop>
</tool>

<tool name="clear_completed" description="Remove all completed tasks"></tool>

<context name="tasks" id="tasks-ctx"></context>
<context name="task_list" id="task-list-ctx"></context>

<ul id="task-ul"></ul>

<script>
  const tasks = [];
  let nextId = 1;

  const ul = document.getElementById("task-ul");
  const ctxMain = document.getElementById("tasks-ctx");
  const ctxList = document.getElementById("task-list-ctx");

  function render() {
    ctxMain.textContent = `Total tasks: ${tasks.length}
  Active: ${tasks.filter((t) => !t.completed).length}
  Completed: ${tasks.filter((t) => t.completed).length}
  Task IDs: ${tasks.map((t) => t.id).join(", ")}`;

    ctxList.textContent = tasks.length
      ? tasks
          .map(
            (t) =>
              `- ${t.title} (${t.id}) – ${
                t.completed ? "Completed" : "Pending"
              } [${t.priority}]`
          )
          .join("\n")
      : "";

    ul.innerHTML = "";
    tasks.forEach((t) => {
      const li = document.createElement("li");
      li.dataset.priority = t.priority;
      li.textContent = `${t.title} [${t.id}]${t.completed ? " ✅" : ""}`;
      ul.appendChild(li);
    });
  }

  // add_task
  document
    .querySelector('tool[name="add_task"]')
    .addEventListener("call", (e) => {
      const { title, priority = "medium" } = e.detail;
      const task = {
        id: `task-${nextId++}`,
        title,
        priority,
        completed: false,
      };
      tasks.push(task);
      render();
      e.target.dispatchEvent(
        new CustomEvent("return", {
          detail: { taskId: task.id, status: "added successfully" },
        })
      );
    });

  // complete_task
  document
    .querySelector('tool[name="complete_task"]')
    .addEventListener("call", (e) => {
      const t = tasks.find((x) => x.id === e.detail.taskId);
      if (t) {
        t.completed = true;
        render();
      }
    });

  // delete_task
  document
    .querySelector('tool[name="delete_task"]')
    .addEventListener("call", (e) => {
      const idx = tasks.findIndex((x) => x.id === e.detail.taskId);
      if (idx !== -1) {
        tasks.splice(idx, 1);
        render();
      }
    });

  // clear_completed
  document
    .querySelector('tool[name="clear_completed"]')
    .addEventListener("call", () => {
      for (let i = tasks.length - 1; i >= 0; i--) {
        if (tasks[i].completed) tasks.splice(i, 1);
      }
      render();
    });

  // Initial render
  render();
</script>

Try It

Try these with VOIX:

  • "Add a task called 'Review documentation' with high priority"
  • "Complete task-1"
  • "Delete the second task"
  • "Add 'Write tests' as a low priority task"
  • "Clear all completed tasks"

TODO List:

    Released under the MIT License.