Sagents.Todo (Sagents v0.8.0-rc.11)
Copy MarkdownTODO item structure for task tracking.
TODOs help agents break down complex tasks into manageable steps and track progress through multi-step workflows.
Identity
Each TODO's id is a positive integer that is unique within a single
list. There is no global ID space — IDs only need to distinguish items
within the same conversation's todo list. When building a list, prefer
list_from_maps/1, which assigns positional IDs (1..N) for any item that
doesn't supply one.
Status Values
:pending- Task not yet started:in_progress- Currently being worked on:completed- Task finished successfully:cancelled- Task no longer needed
Usage
# Create a single TODO (id is required)
{:ok, todo} = Todo.new(%{id: 1, content: "Implement user authentication"})
# Build a list, letting positional defaults assign IDs
{:ok, todos} = Todo.list_from_maps([
%{"content" => "Task A", "status" => "pending"},
%{"content" => "Task B", "status" => "pending"}
])
# todos[0].id == 1, todos[1].id == 2
Summary
Functions
Create a single TODO from a map (for deserialization).
Build a list of TODOs from an ordered list of maps.
Create a new TODO item with validation.
Create a new TODO item, raising on error.
Convert a TODO struct to a map for serialization.
Types
Functions
Create a single TODO from a map (for deserialization).
Coerces a stringified integer id to an integer. A missing or non-numeric
id is an error from this entry point; callers handling a whole list
should use list_from_maps/1 to get positional ID defaults.
Examples
{:ok, todo} = Todo.from_map(%{"id" => 1, "content" => "Task", "status" => "pending"})
{:ok, todo} = Todo.from_map(%{"id" => "1", "content" => "Task"})
Build a list of TODOs from an ordered list of maps.
This is the canonical ingest point for any list of incoming todo data: tool calls, persisted state, conversation rehydrate. It guarantees every TODO has a positive integer id by assigning positional defaults:
- Missing, nil, or non-numeric id →
id = index + 1(1-based). - Positive integer id → kept as is.
- Numeric-string id (e.g.
"5","01") → coerced to integer.
The non-numeric fallback exists for backward compatibility with snapshots persisted before IDs were typed as integers (which used random base64 strings). Those legacy IDs lose their original identity on reload, but in-list order is preserved.
Returns {:ok, [Todo.t()]} if every item parses, or {:error, reason}
on the first failure.
Create a new TODO item with validation.
Requires an explicit positive-integer id. There is no auto-generation —
callers building a list should use list_from_maps/1 instead, which
assigns positional IDs.
Stringified integer ids (e.g. "5") are coerced to integers so payloads
arriving from JSON tool calls keep working.
Examples
{:ok, todo} = Todo.new(%{id: 1, content: "Write tests"})
{:ok, todo} = Todo.new(%{id: "1", content: "Write tests"}) # coerced
Create a new TODO item, raising on error.
Examples
todo = Todo.new!(%{id: 1, content: "Deploy to production"})
Convert a TODO struct to a map for serialization.
Examples
todo = Todo.new!(%{id: 1, content: "Task"})
map = Todo.to_map(todo)
# => %{"id" => 1, "content" => "Task", "status" => "pending"}