---
sidebar:
  hidden: true
title: roboto.ai.goals.results
---
Typed, per-goal-type results bundling the achieve-tool invocation.

A [`GoalResult`](/docs/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResult) is the typed read shape an SDK caller gets back from [`AgentThreadGoalView.result`](/docs/reference/python-sdk/roboto/ai/agent_thread#roboto.ai.agent_thread.AgentThreadGoalView.result) once a goal has reached a terminal state (`ACHIEVED` or `FAILED` with at least one attempted invocation). It bundles together:

- The goal's terminal [`AgentGoalStatus`](/docs/reference/python-sdk/roboto/ai/goals#roboto.ai.goals.AgentGoalStatus).
- The exact [`AgentToolUseContent`](/docs/reference/python-sdk/roboto/ai/agent_thread#roboto.ai.agent_thread.AgentToolUseContent) the LLM submitted to satisfy the goal — useful when callers need to introspect the request or correlate with downstream effects.
- The corresponding [`AgentToolResultContent`](/docs/reference/python-sdk/roboto/ai/agent_thread#roboto.ai.agent_thread.AgentToolResultContent) (when the runner observed one), so callers can see the response the LLM saw.
- Per-goal-type typed fields parsed from `achieve_tool_use.input` via the shared [`roboto.ai.goals.achieve_inputs`](/docs/reference/python-sdk/roboto/ai/goals/achieve_inputs) models, so callers get `result.summary`, `result.label_decisions`, `result.events` directly instead of reaching into a raw dict.

The discriminated-union pattern mirrors [`AgentGoal`](/docs/reference/python-sdk/roboto/ai/goals#roboto.ai.goals.AgentGoal) exactly: each concrete subclass declares `goal_type: Literal[GoalType.X] = GoalType.X` and the union dispatches on that discriminator.

Validation lives in the SDK, not on the wire — the server emits `achieve_tool_use_id` (a pointer into the persisted message stream) and the SDK rebuilds the [`GoalResult`](/docs/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResult) from messages it already holds. A new goal type therefore needs no API change, only a new subclass here plus a corresponding entry in [`AgentGoal`](/docs/reference/python-sdk/roboto/ai/goals#roboto.ai.goals.AgentGoal).

## Module Contents

### CreateEventsGoalResult

```python
class roboto.ai.goals.results.CreateEventsGoalResult(/, **data: Any)
```

`from roboto.ai.goals import CreateEventsGoalResult`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/ai/goals/results.py#L114-L126)

Bases: [`GoalResultBase`](/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResultBase), [`roboto.ai.goals.achieve_inputs.CreateEventsAchieveInput`](/reference/python-sdk/roboto/ai/goals/achieve_inputs#roboto.ai.goals.achieve_inputs.CreateEventsAchieveInput)

Result of a [`GoalType.CREATE_EVENTS`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.GoalType.CREATE_EVENTS) achieve-tool invocation.

Exposes the list of `EventSpec` objects the LLM submitted. The SDK does not currently surface the resulting event ids directly from this result — callers wanting the created events should query the dataset's events using the time bounds in [`events`](/reference/python-sdk/roboto/ai/goals/achieve_inputs#roboto.ai.goals.achieve_inputs.CreateEventsAchieveInput.events). (Surfacing event ids here would require an API-layer round-trip back to the achieve-tool's response payload; YAGNI until a caller needs it.)

**Parameters**

- **data** (`Any`)

**Attributes**

- **CreateEventsGoalResult.goal_type** (`Literal[roboto.ai.goals.types.GoalType.CREATE_EVENTS]`): Discriminator. Always [`GoalType.CREATE_EVENTS`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.GoalType.CREATE_EVENTS).

### DatasetSummaryGoalResult

```python
class roboto.ai.goals.results.DatasetSummaryGoalResult(/, **data: Any)
```

`from roboto.ai.goals import DatasetSummaryGoalResult`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/ai/goals/results.py#L80-L88)

Bases: [`GoalResultBase`](/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResultBase), [`roboto.ai.goals.achieve_inputs.DatasetSummaryAchieveInput`](/reference/python-sdk/roboto/ai/goals/achieve_inputs#roboto.ai.goals.achieve_inputs.DatasetSummaryAchieveInput)

Result of a [`GoalType.DATASET_SUMMARY`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.GoalType.DATASET_SUMMARY) achieve-tool invocation.

Exposes the LLM-submitted `summary` directly alongside the raw `achieve_tool_use` / `achieve_tool_result` blocks.

**Parameters**

- **data** (`Any`)

**Attributes**

- **DatasetSummaryGoalResult.goal_type** (`Literal[roboto.ai.goals.types.GoalType.DATASET_SUMMARY]`): Discriminator. Always [`GoalType.DATASET_SUMMARY`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.GoalType.DATASET_SUMMARY).

### DatasetTriageGoalResult

```python
class roboto.ai.goals.results.DatasetTriageGoalResult(/, **data: Any)
```

`from roboto.ai.goals import DatasetTriageGoalResult`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/ai/goals/results.py#L91-L111)

Bases: [`GoalResultBase`](/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResultBase), [`roboto.ai.goals.achieve_inputs.DatasetTriageAchieveInput`](/reference/python-sdk/roboto/ai/goals/achieve_inputs#roboto.ai.goals.achieve_inputs.DatasetTriageAchieveInput)

Result of a [`GoalType.DATASET_TRIAGE`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.GoalType.DATASET_TRIAGE) achieve-tool invocation.

Exposes the full per-label deliberation in `label_decisions`; use [`applied_labels`](/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.DatasetTriageGoalResult.applied_labels) for the convenience subset that actually became tags on the dataset.

**Parameters**

- **data** (`Any`)

**Attributes**

- **DatasetTriageGoalResult.goal_type** (`Literal[roboto.ai.goals.types.GoalType.DATASET_TRIAGE]`): Discriminator. Always [`GoalType.DATASET_TRIAGE`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.GoalType.DATASET_TRIAGE).

**Properties**

- **DatasetTriageGoalResult.applied_labels** (`list[str]`): Labels for which the LLM voted `applies=True`.

  Matches the set of tags the achieve-tool persisted on the dataset. Returned in declaration order, not the (sorted) order in which the achieve-tool writes them to the dataset; for stable ordering use `sorted(result.applied_labels)`.

### GoalResult

```python
roboto.ai.goals.results.GoalResult
```

`from roboto.ai.goals import GoalResult`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/ai/goals/results.py#L129-L132)

Closed, Roboto-controlled discriminated union of every typed goal result.

Validated via pydantic discriminator on `goal_type`. Mirrors the shape of [`AgentGoal`](/reference/python-sdk/roboto/ai/goals/types#roboto.ai.goals.types.AgentGoal) so adding a new goal type means:

1. Add a new `GoalType` member.
2. Add a new `AgentGoal` subclass in [`roboto.ai.goals.types`](/reference/python-sdk/roboto/ai/goals/types).
3. Add a matching achieve-input model in [`roboto.ai.goals.achieve_inputs`](/reference/python-sdk/roboto/ai/goals/achieve_inputs).
4. Add a new `GoalResult` subclass here that inherits from both [`GoalResultBase`](/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResultBase) and the new achieve-input model.

No API or wire-schema change is needed because the SDK builds the result from the persisted message stream via `achieve_tool_use_id`.

### GoalResultBase

```python
class roboto.ai.goals.results.GoalResultBase(/, **data: Any)
```

`from roboto.ai.goals import GoalResultBase`

[Source](https://github.com/roboto-ai/roboto-python-sdk/blob/main/src/roboto/ai/goals/results.py#L56-L77)

Bases: `pydantic.BaseModel`

Shared base for every concrete [`GoalResult`](/reference/python-sdk/roboto/ai/goals/results#roboto.ai.goals.results.GoalResult).

Subclasses must declare a literal-typed `goal_type` field so the discriminated union can dispatch — and must also inherit from the matching achieve-input model from [`roboto.ai.goals.achieve_inputs`](/reference/python-sdk/roboto/ai/goals/achieve_inputs) so the parsed typed fields land alongside the raw blocks.

**Parameters**

- **data** (`Any`)

**Attributes**

- **GoalResultBase.achieve_tool_result** (`roboto.ai.core.content.AgentToolResultContent | None`) = `None`: The `AgentToolResultContent` the runner observed for the matching `tool_use_id`, if any. `None` when the runner persisted a tool_use but no corresponding tool_result reached the chunk log before the turn terminated.
- **GoalResultBase.achieve_tool_use** (`roboto.ai.core.content.AgentToolUseContent`): The `AgentToolUseContent` the LLM submitted. `input` carries the raw arguments; the parsed typed fields on the subclass are derived from it.
- **GoalResultBase.status** (`roboto.ai.goals.types.AgentGoalStatus`): Terminal status of the goal: `ACHIEVED` or `FAILED`.
