[integrations] Preserve finish_reason for Anthropic and Watsonx responses
- Dominant language
- Java
- Stars
- 452
- Forks
- 167
- Avg merge
- 5d 9h
- Merged PRs (30d)
- 49
Description
### 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.
Contributor guide
Research direction
Start with the Java and Python Anthropic and Watsonx connection responses, then inspect the SDK response fixtures and existing Java/Python tests. Verify capture with and without usage, missing and unknown reasons, outbound serialization, and the shared rejection/error-strategy path; done means Watsonx preserves reported reasons while Anthropic applies the stated mapping without adding missing metadata.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100