Skip to content

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

Closed

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_tokens → length, end_turn/stop_sequence → stop, and tool_use → tool_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_tokens → length 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

  1. added
    feature[Issue Type] New features or improvements to existing features.
    on Sep 14, 2026
  2. CodeTrainerMan commented on Sep 18, 2026

    @CodeTrainerMan
    Contributor

    Thanks for the detailed breakdown. I would like to take the Watsonx portion.

    It is independent from the Anthropic mapping already submitted in #1107, and the scope you described is unambiguous, so I plan to follow it exactly:

    • retain the reason reported by the provider verbatim (Watsonx already emits the shared vocabulary, so no mapping table is needed);
    • add no metadata key when the provider reports no finish reason;
    • keep the finish-reason metadata out of the outbound provider payload;
    • cover both the Java and Python Watsonx chat model connections, with tests.

    Before I write code I have two questions so the first PR lands in the right shape:

    1. Naming: should the metadata key match the one [integrations][anthropic][java][python] Preserve Anthropic finish reason #1107 introduced for Anthropic (I will read that patch and follow it) or is there a shared constant for finish reason that both providers are expected to use?
    2. Does Watsonx need to go through the shared response path from [integrations][plan] Handle finish_reason in OpenAI-family connections #1040 the same way [integrations][anthropic][java][python] Preserve Anthropic finish reason #1107 does for Anthropic, or is it wired up differently?

    I will keep the PR scoped to Watsonx only and wait for your ack before opening it.

  3. wenjin272 commented on Sep 22, 2026

    @wenjin272
    Contributor

    Thanks for offering to help @CodeTrainerMan. Both portions have already been merged: Anthropic in #1107 and Watsonx in #1113. Sorry—the issue description was outdated and still marked Watsonx as unstarted. No additional implementation is needed for this issue.

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

    feature[Issue Type] New features or improvements to existing features.fixVersion/missingThe Bot applies this label when fixVersion is not set.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions