upsert_commentary
Create or edit narrative analysis on a model run, or on one named output of the run. action is a closed enum: action=‘create’ creates a new row at version=1 and requires run_id (with optional output_name); action=‘update’ edits an existing row and requires commentary_id plus expected_version under optimistic concurrency. The two modes reject each other’s fields.
Parameters
Section titled “Parameters”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
action | Annotated[Literal['create', 'update'], Field(description='Create a new commentary row or update one existing row.')] | Yes | — | |
text | Annotated[str, Field(description='Commentary text content.')] | Yes | — | |
commentary_id | Annotated[str, Field(description='UUID of an existing commentary row to UPDATE. Omit to CREATE a new row instead (run_id becomes required).')] | No | '' | |
run_id | Annotated[str, Field(description='UUID of the model run to attach a new commentary row to. Required when commentary_id is omitted (create); ignored otherwise.')] | No | '' | |
output_name | Annotated[str, Field(description='Named output within the run that this commentary describes. Create-only; ignored when commentary_id is set.')] | No | '' | |
expected_version | `Annotated[int | None, Field(description=‘Expected current version, for optimistic concurrency control. Required when commentary_id is set (update); ignored otherwise.’)]` | No | None |
change_note | Annotated[str, Field(description='Optional brief note describing what changed in this version of the commentary.')] | No | '' | |
workspace_id | `Annotated[str | None, Field(description=ID_BACKED_WORKSPACE_ID_FIELD_DESCRIPTION)]` | No | None |
Returns
Section titled “Returns”Returns a structured object. Top-level fields:
commentary(object)
See the response example below for the full payload shape.
Example
Section titled “Example”Tool Call
Section titled “Tool Call”{ "name": "upsert_commentary", "arguments": { "action": "update", "commentary_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "text": "Revenue beat plan by 14% after FX rebase; SaaS expansion remains the primary driver.", "expected_version": 1, "change_note": "Revised after FX rebase" }}Response
Section titled “Response”{ "commentary": { "commentary_id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "workspace_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", "model_name": "forecasts", "run_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee", "output_name": "revenue", "author": { "kind": "human", "display_name": "Analyst" }, "text": "Revenue beat plan by 14% after FX rebase; SaaS expansion remains the primary driver.", "version": 2, "archived_at": null, "archived_by": null, "created_at": "2026-04-28T10:00:00+00:00", "updated_at": "2026-04-28T10:05:00+00:00" }}- Module:
Run Commentary - Requires an authenticated Bridge Town session (OAuth) or an API token.