Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .spec-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cddf1ca71c61a62e9e429206b74a6d064222b4ed
25958e9afda3dab55f5928054d2860c6f78d48ec
7 changes: 3 additions & 4 deletions src/onepin/.fern/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
}
]
},
"originGitCommit": "a3ee57d10e66cc74651c81add046845159caf420",
"originGitCommitIsDirty": false,
"invokedBy": "ci",
"ciProvider": "github"
"originGitCommit": "b2e32490c9795d004581bca295158bfa60cb8140",
"originGitCommitIsDirty": true,
"invokedBy": "manual"
}
20 changes: 18 additions & 2 deletions src/onepin/_cli/_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ def _list_opts(*extra: Opt) -> list[Opt]:
# Workflow run status filter / terminal states (SDK exposes run status as raw str; no enum).
_RUN_STATUS = ("draft", "running", "completed", "failed", "paused", "cancelled", "pending")

_NODE_TYPES = (
"source_script",
"operator_translator",
"operator_normalizer",
"operator_generator",
"sink_preview",
"validator_error_rate",
"validator_naturalness",
"validator_noise",
)

# Column presets keyed by output model.
_COLS_WORKFLOW = ["id", "name", "runs_count", "last_run_status", "updated_at"]
_COLS_VOICE = ["id", "name", "provider", "gender", "category"]
Expand Down Expand Up @@ -283,11 +294,16 @@ def _list_opts(*extra: Opt) -> list[Opt]:
Cmd(
"workflows",
"steps",
"workflows.get_run_steps",
"workflows.runs.steps",
"List the steps of a run.",
subgroup="runs",
args=[("workflow_id", "Workflow UUID."), ("run_id", "Run UUID.")],
options=[_JSON],
options=[
Opt("--include-result", "bool", False, help="Include each step's full result payload."),
Opt("--node-type", _NODE_TYPES, None, help="Filter by node type."),
Opt("--node-id", "str", None, help="Filter by node ID."),
_JSON,
],
unwrap="list",
columns=[],
),
Expand Down
250 changes: 138 additions & 112 deletions src/onepin/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -6867,112 +6867,6 @@ client.workflows.runs_summary(
</dl>


</dd>
</dl>
</details>

<details><summary><code>client.workflows.<a href="src/onepin/workflows/client.py">get_run_steps</a>(...) -> ApiResponseListWorkflowRunStepOut</code></summary>
<dl>
<dd>

#### 📝 Description

<dl>
<dd>

<dl>
<dd>

List per-node execution steps for a workflow run.

Returns one entry per node execution attempt, ordered by execution sequence.
Each step includes the node type, status, iteration number (for nodes that
are retried), start/completion timestamps, and the node's `result` output.

For audio output nodes, `result` is hydrated with short-lived `playback_url`
values (valid for 15 minutes) so callers can stream audio directly without
a separate download step.

`node_display_name` is resolved from the run's definition snapshot, so it
reflects the name the node had when the run executed. Repeated executions of
the same node share that name and are distinguished by `iteration`.

For a higher-level view with aggregated metrics (pass rates, audio duration
by language), use `GET /runs/{run_id}/overview`. For paginated, grouped
script+audio rows suitable for a data table, use `GET /runs/{run_id}/data`.
</dd>
</dl>
</dd>
</dl>

#### 🔌 Usage

<dl>
<dd>

<dl>
<dd>

```python
from onepin import OnePinClient
from onepin.environment import OnePinClientEnvironment

client = OnePinClient(
token="<token>",
environment=OnePinClientEnvironment.PROD,
)

client.workflows.get_run_steps(
workflow_id="workflow_id",
run_id="run_id",
)

```
</dd>
</dl>
</dd>
</dl>

#### ⚙️ Parameters

<dl>
<dd>

<dl>
<dd>

**workflow_id:** `str`

</dd>
</dl>

<dl>
<dd>

**run_id:** `str`

</dd>
</dl>

<dl>
<dd>

**workspace_id:** `typing.Optional[str]`

</dd>
</dl>

<dl>
<dd>

**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.

</dd>
</dl>
</dd>
</dl>


</dd>
</dl>
</details>
Expand Down Expand Up @@ -7101,7 +6995,8 @@ completes. It differs from the other run sub-resources as follows:

- `GET /runs/{run_id}` — full run record including the raw definition snapshot.
- `GET /runs/{run_id}/status` — volatile status fields only; for polling.
- `GET /runs/{run_id}/steps` — flat per-node step log with audio playback URLs.
- `GET /runs/{run_id}/steps` — lightweight per-node step log by default;
`include_result=true` includes results and audio playback URLs.
- `GET /runs/{run_id}/outputs` — one logical result per snapshot sink node.
- `GET /runs/{run_id}/data` — paginated script+audio rows for a data table.
- `GET /runs/{run_id}/overview` (this endpoint) — pre-aggregated metrics and
Expand Down Expand Up @@ -8101,7 +7996,8 @@ workflow definition has since been edited.
This is the heaviest run endpoint. For progress polling, use the lighter
`GET /runs/{run_id}/status` which omits the snapshot. For aggregated
visual metrics, use `GET /runs/{run_id}/overview`. For the per-node step
log with audio playback URLs, use `GET /runs/{run_id}/steps`.
log, use `GET /runs/{run_id}/steps`; opt into full results and audio
playback URLs with `include_result=true`.
</dd>
</dl>
</dd>
Expand Down Expand Up @@ -8281,6 +8177,137 @@ client.workflows.runs.status(
</dl>


</dd>
</dl>
</details>

<details><summary><code>client.workflows.runs.<a href="src/onepin/workflows/runs/client.py">steps</a>(...) -> ApiResponseListWorkflowRunStepOut</code></summary>
<dl>
<dd>

#### 📝 Description

<dl>
<dd>

<dl>
<dd>

List per-node execution steps for a workflow run.

Returns one entry per node execution attempt, ordered by execution sequence.
By default, the response is lightweight: `result` is null, `has_result`
reports whether a stored result exists, and `active_ports` is projected from
the result without loading the full JSON payload.

Set `include_result=true` to restore the full result payload. Audio results
are then hydrated with short-lived `playback_url` values (valid for 15
minutes). `node_type` and `node_id` filters combine with AND semantics.

`node_display_name` is resolved from the run's definition snapshot, so it
reflects the name the node had when the run executed. Repeated executions of
the same node share that name and are distinguished by `iteration`.

For a higher-level view with aggregated metrics (pass rates, audio duration
by language), use `GET /runs/{run_id}/overview`. For paginated, grouped
script+audio rows suitable for a data table, use `GET /runs/{run_id}/data`.
</dd>
</dl>
</dd>
</dl>

#### 🔌 Usage

<dl>
<dd>

<dl>
<dd>

```python
from onepin import OnePinClient
from onepin.environment import OnePinClientEnvironment

client = OnePinClient(
token="<token>",
environment=OnePinClientEnvironment.PROD,
)

client.workflows.runs.steps(
workflow_id="workflow_id",
run_id="run_id",
)

```
</dd>
</dl>
</dd>
</dl>

#### ⚙️ Parameters

<dl>
<dd>

<dl>
<dd>

**workflow_id:** `str`

</dd>
</dl>

<dl>
<dd>

**run_id:** `str`

</dd>
</dl>

<dl>
<dd>

**include_result:** `typing.Optional[bool]` — Include the full step result payload and hydrate audio playback URLs.

</dd>
</dl>

<dl>
<dd>

**node_type:** `typing.Optional[NodeType]` — Filter steps by node type.

</dd>
</dl>

<dl>
<dd>

**node_id:** `typing.Optional[str]` — Filter steps by node ID.

</dd>
</dl>

<dl>
<dd>

**workspace_id:** `typing.Optional[str]`

</dd>
</dl>

<dl>
<dd>

**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.

</dd>
</dl>
</dd>
</dl>


</dd>
</dl>
</details>
Expand All @@ -8304,9 +8331,9 @@ In-flight work at the current node may be abandoned mid-execution. The
operation is idempotent: cancelling an already-cancelled run returns the
run unchanged without error.

Only runs in `pending`, `running`, or `paused` status can be cancelled.
Runs that have already reached a terminal state (`completed`, `failed`,
`cancelled`) return 409.
Runs already in a terminal state (`completed`, `failed`, or `cancelled`)
are returned unchanged. Concurrent terminalization is also treated as an
idempotent success; a still-active compare-and-swap loser returns 409.

Unlike `pause`, cancel is permanent — a cancelled run cannot be resumed.
Use `pause` if you intend to continue the run later.
Expand Down Expand Up @@ -8386,4 +8413,3 @@ client.workflows.runs.cancel(
</dd>
</dl>
</details>

Loading