# `ExMCP.Tasks.Task`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/tasks/task.ex#L1)

Task struct and state machine validation for MCP Tasks.

Tasks represent async operations initiated by tool calls. This module
provides a pure data structure and state transition validation functions.
`ExMCP.Tasks` and `ExMCP.Tasks.Store` provide the optional durable lifecycle
boundary; the task struct itself does not own a process.

## State Machine

Valid states: `:working`, `:input_required`, `:completed`, `:failed`, `:cancelled`

Valid transitions:
- `:working` -> `:input_required` | `:completed` | `:failed` | `:cancelled`
- `:input_required` -> `:working` | `:cancelled`
- `:completed` -> (terminal state)
- `:failed` -> (terminal state)
- `:cancelled` -> (terminal state)

## Usage

    task = ExMCP.Tasks.Task.new("my-tool", %{"arg" => "value"})
    {:ok, task} = ExMCP.Tasks.Task.transition(task, :completed)

# `state`

```elixir
@type state() :: :working | :input_required | :completed | :failed | :cancelled
```

# `t`

```elixir
@type t() :: %ExMCP.Tasks.Task{
  arguments: map(),
  created_at: String.t(),
  error: map() | nil,
  id: String.t(),
  input_requests: map() | nil,
  last_updated_at: String.t() | nil,
  metadata: map(),
  poll_interval: integer() | nil,
  result: map() | nil,
  state: state(),
  status_message: String.t() | nil,
  tool_name: String.t(),
  ttl: integer() | nil
}
```

# `complete`

```elixir
@spec complete(t(), map()) :: {:ok, t()} | {:error, String.t()}
```

Transitions and sets the result (for completed tasks).

# `fail`

```elixir
@spec fail(t(), map()) :: {:ok, t()} | {:error, String.t()}
```

Transitions to failed state with error info.

# `new`

```elixir
@spec new(String.t(), map(), keyword()) :: t()
```

Creates a new task in the `:working` state.

## Parameters
- `tool_name` - Name of the tool this task is executing
- `arguments` - Tool arguments
- `opts` - Optional fields: `:id`, `:ttl`, `:metadata`

# `parse_state`

```elixir
@spec parse_state(String.t()) :: {:ok, state()} | {:error, String.t()}
```

Parses a state string to a state atom.

# `require_input`

```elixir
@spec require_input(t(), map()) :: {:ok, t()} | {:error, String.t()}
```

Transitions a task to `input_required` with outstanding input requests.

# `states`

```elixir
@spec states() :: [state()]
```

Returns all valid states.

# `terminal?`

```elixir
@spec terminal?(t()) :: boolean()
```

Checks if the task is in a terminal state.

# `terminal_states`

```elixir
@spec terminal_states() :: [state()]
```

Returns all terminal states.

# `to_map`

```elixir
@spec to_map(t()) :: map()
```

Converts a task to a map suitable for protocol serialization.

# `to_map`

```elixir
@spec to_map(t(), :legacy | :modern | String.t()) :: map()
```

Converts a task to the wire representation for a protocol era or version.

# `transition`

```elixir
@spec transition(t(), state()) :: {:ok, t()} | {:error, String.t()}
```

Attempts a state transition.

Returns `{:ok, updated_task}` if the transition is valid,
`{:error, reason}` if invalid.

# `valid_transition?`

```elixir
@spec valid_transition?(state(), state()) :: boolean()
```

Checks if a transition from one state to another is valid.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
