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.
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_reasonin 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, andtool_use→tool_calls. Preserve unrecognized reasons, includingmodel_context_window_exceededandrefusal, verbatim for now. Mapping context exhaustion tolengthwould currently tell users to increase output tokens, which may be the wrong remedy; treating a refusal ascontent_filterwould 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→lengthmapping in Java and Python, and preserves every other suppliedAnthropic 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.