Skip to content

[integrations] Preserve finish_reason for Anthropic and Watsonx responses #1106

Description

@emecii

Motivation

Follow-up to #936 and merged #1040. The shared response path now checks finish_reason, but Anthropic still has the capture TODO identified in #936; Watsonx parses a reason without preserving it in message metadata. Those providers therefore do not consistently participate in the shared handling.

#1040 explicitly checks the common path before text, structured output, or tool dispatch, and its approval acknowledges that design. This proposal follows that accepted behavior rather than moving the gate.

Proposed scope

Capture finish_reason in the Java and Python Anthropic and Watsonx connection responses, preserving content and the existing provider-specific content blocks.

For Anthropic, propose max_tokenslength, end_turn/stop_sequencestop, and tool_usetool_calls. Preserve unrecognized reasons, including model_context_window_exceeded and refusal, verbatim for now. Mapping context exhaustion to length would currently tell users to increase output tokens, which may be the wrong remedy; treating a refusal as content_filter would add a new rejection decision.

For Watsonx, retain its reported reason verbatim. Missing reasons should not add a metadata key. Keep finish-reason metadata out of outbound provider requests, while preserving Anthropic content-block round trips.

Scope status

The narrow Anthropic portion is now submitted in PR #1107. It implements only the directly
equivalent max_tokenslength mapping in Java and Python, and preserves every other supplied
Anthropic reason unchanged. Its scope follows the explicit Anthropic follow-up identified by
@weiqingy on #936 and the shared-path behavior accepted in #1040.

Watsonx remains an independent, unstarted follow-up. Because it already emits the shared
vocabulary, retaining the reason is mechanically separate from the Anthropic mapping; it should
be reviewed independently rather than enlarging #1107.

Validation and scope decision

Use SDK response fixtures and Java/Python tests for capture with and without usage, missing and unknown reasons, outbound serialization, and the existing shared rejection/error-strategy path. No live-provider performance or model-quality claims are proposed.

The direct committer guidance in #936 supports metadata capture and the shared action's handling of
canonical reasons. The two Anthropic reasons above remain native until shared diagnostics and
rejection semantics are decided.

Prepared with OpenAI Codex assistance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions