Skip to content

feat(task-messages): add optional is_error to ToolResponseContent#331

Merged
declan-scale merged 1 commit into
mainfrom
declan-scale/agx1-371-tool-response-is-error
Jun 22, 2026
Merged

feat(task-messages): add optional is_error to ToolResponseContent#331
declan-scale merged 1 commit into
mainfrom
declan-scale/agx1-371-tool-response-is-error

Conversation

@declan-scale

@declan-scale declan-scale commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds an additive optional is_error: bool | None field to ToolResponseContent (API schema + domain entity), threaded through the schema→entity converter. agentex/openapi.yaml is regenerated accordingly.

Why (AGX1-371)

The unified harness surface in scale-agentex-python derives tool spans from the canonical StreamTaskMessage* stream and closes a tool span on the matching ToolResponseContent. Today there is no structured error status on ToolResponseContent — tool failures are only encoded as an "Error: ..." string inside the opaque content field — so a derived tool span cannot mark failure.

Harnesses that track tool errors (e.g. golden agent's ToolCompleted.is_error) lose that status the moment they normalize onto the harness surface, which is a tracing-fidelity regression flagged in review on scaleapi/scale-agentex-python#412.

Since it's an additive optional field, landing it here first (then regenerating the SDK) unblocks wiring the status onto the closed tool span in the harness.

Changes

  • agentex/src/api/schemas/task_messages.pyToolResponseContent.is_error: bool | None = None
  • agentex/src/domain/entities/task_messages.py — same field on ToolResponseContentEntity + carried through convert_task_message_content_to_entity
  • agentex/openapi.yaml — regenerated (is_error-only diff)

Defaults to None when the harness reports no status, so existing producers/consumers are unaffected.

Follow-up

After this lands and the SDK is regenerated, the harness PRs in scale-agentex-python wire ToolResponseContent.is_errorCloseSpan → span status, and the parallel-tools-with-error conformance fixture is extended to assert error status propagates.

🤖 Generated with Claude Code

Greptile Summary

Adds an optional is_error: bool | None = None field to ToolResponseContent (API schema) and ToolResponseContentEntity (domain entity), carrying it through the schema→entity converter. The openapi.yaml is regenerated to reflect the new field.

  • The field defaults to None, making this fully additive and backward-compatible with all existing producers and consumers.
  • The converter at convert_task_message_content_to_entity now explicitly passes is_error=content.is_error to the entity constructor, ensuring the field propagates correctly from API layer to persistence.
  • Existing construction sites in agents_acp_use_case.py that build ToolResponseContentEntity directly (e.g. the streaming delta accumulator) do not pass is_error, which is safe because the default is None.

Confidence Score: 5/5

Safe to merge — purely additive optional field with a None default that leaves all existing producers and consumers untouched.

The change is a single optional field added in three consistent places (API schema, domain entity, converter). The default of None means no existing code path needs updating, and the OpenAPI spec regeneration matches the Python changes exactly.

No files require special attention.

Important Files Changed

Filename Overview
agentex/src/api/schemas/task_messages.py Adds optional `is_error: bool
agentex/src/domain/entities/task_messages.py Mirrors is_error on ToolResponseContentEntity and threads it through convert_task_message_content_to_entity; no existing callers broken since the field defaults to None
agentex/openapi.yaml Regenerated to include is_error in ToolResponseContent and ToolResponseContentEntityOptional schemas; diff is consistent with the Python-side changes

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Harness as Harness (scale-agentex-python)
    participant API as API Schema<br/>(ToolResponseContent)
    participant Converter as convert_task_message_content_to_entity
    participant Entity as Domain Entity<br/>(ToolResponseContentEntity)
    participant ACP as ACP Service<br/>(model_validate)

    Harness->>API: "POST /messages { is_error: true | false | null }"
    API->>Converter: ToolResponseContent (with is_error)
    Converter->>Entity: "ToolResponseContentEntity(is_error=content.is_error)"
    Note over Entity: Stored in MongoDB

    ACP->>Entity: ToolResponseContentEntity.model_validate(result)
    Note over ACP: is_error carried through if present in result dict
    Entity-->>Harness: "Stream back via StreamTaskMessage*"
    Note over Harness: Can now close tool span with correct error status
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Harness as Harness (scale-agentex-python)
    participant API as API Schema<br/>(ToolResponseContent)
    participant Converter as convert_task_message_content_to_entity
    participant Entity as Domain Entity<br/>(ToolResponseContentEntity)
    participant ACP as ACP Service<br/>(model_validate)

    Harness->>API: "POST /messages { is_error: true | false | null }"
    API->>Converter: ToolResponseContent (with is_error)
    Converter->>Entity: "ToolResponseContentEntity(is_error=content.is_error)"
    Note over Entity: Stored in MongoDB

    ACP->>Entity: ToolResponseContentEntity.model_validate(result)
    Note over ACP: is_error carried through if present in result dict
    Entity-->>Harness: "Stream back via StreamTaskMessage*"
    Note over Harness: Can now close tool span with correct error status
Loading

Reviews (2): Last reviewed commit: "feat(task-messages): add optional is_err..." | Re-trigger Greptile

@declan-scale declan-scale requested a review from a team as a code owner June 22, 2026 18:50
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

✱ Stainless preview builds

This PR will update the agentex-sdk SDKs with the following commit messages.

openapi

feat(api): add is_error field to tool result models

python

feat(api): add is_error field to ToolResponseContent

typescript

feat(api): add is_error field to messages ToolResponseContent

Edit this comment to update them. They will appear in their respective SDK's changelogs.

agentex-sdk-openapi studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅

agentex-sdk-typescript studio · code · diff

Your SDK build had at least one "warning" diagnostic, but this did not represent a regression.
generate ⚠️build ✅ (prev: build ⏭️) → lint ✅ (prev: lint ⏭️) → test ✅

npm install https://pkg.stainless.com/s/agentex-sdk-typescript/2d1afe5e4bba796c39f651f8d90f69c74b879d56/dist.tar.gz
agentex-sdk-python studio · code · diff

Your SDK build had at least one "warning" diagnostic, but this did not represent a regression.
generate ⚠️build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/agentex-sdk-python/40291bc3cebcb85fcd7e7876afe4f93f37b9908b/agentex_client-0.13.1-py3-none-any.whl

This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-06-22 19:11:08 UTC

Additive optional field so a tool failure carries a structured status
through to derived tool spans. Without it, harnesses that track tool
errors (e.g. golden agent's ToolCompleted.is_error) lose error status
when normalized onto the unified harness surface — a tracing-fidelity
regression. Defaults to None when the harness reports no status.

Threaded through the domain entity and the schema->entity converter;
the entity->schema path validates by attribute so it carries through.

Regenerating the SDK picks this up as ToolResponseContent.is_error,
unblocking the harness wiring in scale-agentex-python (AGX1-371).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@declan-scale declan-scale force-pushed the declan-scale/agx1-371-tool-response-is-error branch from 8f88a49 to 9a2e334 Compare June 22, 2026 19:08
@declan-scale declan-scale merged commit 5020e96 into main Jun 22, 2026
31 checks passed
@declan-scale declan-scale deleted the declan-scale/agx1-371-tool-response-is-error branch June 22, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants