feat(task-messages): add optional is_error to ToolResponseContent#331
Conversation
✱ Stainless preview buildsThis PR will update the openapi python typescript Edit this comment to update them. They will appear in their respective SDK's changelogs. ✅ agentex-sdk-openapi studio · code · diff
✅ agentex-sdk-typescript studio · code · diff
✅ agentex-sdk-python studio · code · diff
This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push. |
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>
8f88a49 to
9a2e334
Compare
What
Adds an additive optional
is_error: bool | Nonefield toToolResponseContent(API schema + domain entity), threaded through the schema→entity converter.agentex/openapi.yamlis regenerated accordingly.Why (AGX1-371)
The unified harness surface in
scale-agentex-pythonderives tool spans from the canonicalStreamTaskMessage*stream and closes a tool span on the matchingToolResponseContent. Today there is no structured error status onToolResponseContent— tool failures are only encoded as an"Error: ..."string inside the opaquecontentfield — 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.py—ToolResponseContent.is_error: bool | None = Noneagentex/src/domain/entities/task_messages.py— same field onToolResponseContentEntity+ carried throughconvert_task_message_content_to_entityagentex/openapi.yaml— regenerated (is_error-only diff)Defaults to
Nonewhen 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_error→CloseSpan→ span status, and theparallel-tools-with-errorconformance fixture is extended to assert error status propagates.🤖 Generated with Claude Code
Greptile Summary
Adds an optional
is_error: bool | None = Nonefield toToolResponseContent(API schema) andToolResponseContentEntity(domain entity), carrying it through the schema→entity converter. Theopenapi.yamlis regenerated to reflect the new field.None, making this fully additive and backward-compatible with all existing producers and consumers.convert_task_message_content_to_entitynow explicitly passesis_error=content.is_errorto the entity constructor, ensuring the field propagates correctly from API layer to persistence.agents_acp_use_case.pythat buildToolResponseContentEntitydirectly (e.g. the streaming delta accumulator) do not passis_error, which is safe because the default isNone.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
is_erroronToolResponseContentEntityand threads it throughconvert_task_message_content_to_entity; no existing callers broken since the field defaults toNoneis_errorinToolResponseContentandToolResponseContentEntityOptionalschemas; diff is consistent with the Python-side changesSequence 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%%{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 statusReviews (2): Last reviewed commit: "feat(task-messages): add optional is_err..." | Re-trigger Greptile