Pass through unmapped Anthropic stop reasons by PratikDhanave · Pull Request #1117 · microsoft/agent-framework-go · GitHub
Skip to content

Pass through unmapped Anthropic stop reasons - #1117

Open
PratikDhanave (PratikDhanave) wants to merge 3 commits into
microsoft:mainfrom
PratikDhanaveFork:fix/anthropic-stop-reason-passthrough
Open

PratikDhanave (PratikDhanave) wants to merge 3 commits into
microsoft:mainfrom
PratikDhanaveFork:fix/anthropic-stop-reason-passthrough

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

mapStopReason returned "" for any stop_reason not in its fixed set, so a value the Anthropic API may add later — e.g. model_context_window_exceeded — was reported as no finish reason instead of reaching the caller. This affects both the non-streaming path and the streaming final update.

The Python client passes unmapped reasons through unchanged: FINISH_REASON_MAP.get(stop_reason, stop_reason), with an explicit docstring that newer API values like model_context_window_exceeded must still reach the caller.

Change

  • Change the default case to return string(reason). An empty reason still yields "", so the streaming if fr != "" guard is unaffected. StopReason is a plain string in the anthropic SDK.

Test

  • Adds a {"model_context_window_exceeded", "model_context_window_exceeded"} row to the shared finishReasonCases table (runs through both TestNonStreamingFinishReason and TestStreamingFinishReason). Fails before (""), passes after.

mapStopReason returned "" for any stop_reason outside its fixed set, so a
newer value such as model_context_window_exceeded was reported as no finish
reason at all. Pass unmapped reasons through unchanged, matching the Python
client (an empty reason still maps to "").
Copilot AI lite review requested due to automatic review settings September 20, 2026 04:22
@github-actions github-actions Bot added area:provider Changes files in the provider area area:provider/anthropic Changes files in the provider / anthropic area size:small At most 30 changed lines across at most 2 files labels Sep 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Update the stale function comment to document the new pass-through behavior.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Updates Anthropic stop-reason handling so unknown non-empty values reach callers unchanged.

Changes:

  • Passes through unmapped stop reasons.
  • Adds non-streaming and streaming test coverage.
File Description
provider/​anthropicprovider/​agent.go Passes through unknown stop reasons.
provider/​anthropicprovider/​agent_test.go Tests pass-through behavior in both paths.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +256 to +260
// Pass through stop reasons we don't explicitly map (e.g. a newer
// value like model_context_window_exceeded) so they still reach the
// caller instead of being reported as no finish reason, matching the
// Python client. An empty reason maps to "".
return string(reason)
@github-actions github-actions Bot added kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure labels Sep 20, 2026
@github-actions

This comment has been minimized.

Update the stale comment to reflect that only an empty reason returns "";
unrecognized non-empty reasons are now passed through unchanged.
@github-actions github-actions Bot added size:medium At most 100 changed lines across at most 5 files and removed size:small At most 30 changed lines across at most 2 files labels Sep 21, 2026
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added parity-approved Go API consistency review found no parity issues kind:dependencies Changes dependencies or manifests labels Sep 21, 2026
@qmuntal

Copy link
Copy Markdown
Member

Copilot resolve the merge conflicts in this pull request

…reason-passthrough

# Conflicts:
#	go.mod
#	go.sum
@github-actions github-actions Bot added size:small At most 30 changed lines across at most 2 files and removed size:medium At most 100 changed lines across at most 5 files kind:dependencies Changes dependencies or manifests labels Oct 3, 2026
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

API consistency review

Result Scope
aligned user-visible behavior

Changed Go contract

mapStopReason (unexported helper in provider/anthropicprovider/agent.go) now returns string(reason) for unrecognized, non-empty Anthropic stop_reason values instead of "". This is observable through the exported agent.ResponseUpdate.FinishReason field returned by the Anthropic provider's Run/streaming paths (both the non-streaming response and the streaming final-chunk update), so an unmapped stop reason (e.g. a future value like model_context_window_exceeded) now reaches callers as that literal string rather than being silently reported as "no finish reason."

Upstream evidence reviewed

Implementation Source Contract checked
Python python/packages/anthropic/agent_framework_anthropic/_chat_client.py#L242-L261 — FINISH_REASON_MAP and _map_finish_reason Python's _map_finish_reason does FINISH_REASON_MAP.get(stop_reason, stop_reason), explicitly passing through unmapped Anthropic stop reasons unchanged (docstring cites model_context_window_exceeded as the motivating example) rather than returning None/empty.

Assessment

The Go change is a direct, faithful parity fix: it makes the Anthropic provider's unmapped-stop-reason behavior match the Python client's documented pass-through semantics exactly (same motivating example, same fallback-to-raw-value approach), while still returning "" for a genuinely empty reason (matching Python's if not stop_reason: return None). The streaming if fr != "" guard is unaffected since only the empty case still yields "". No .NET equivalent constant/mapping was found under dotnet/src/Microsoft.Agents.AI.Anthropic/, and the vendored C# Anthropic SDK (anthropics/anthropic-sdk-csharp) was not reachable for inspection in this pass, so the comparison relies on the Python reference, which is sufficient to confirm the change is a legitimate parity fix rather than a Go-only divergence. This is an unexported-helper change, so no public Go API surface was added or altered.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

Generated by Go API Consistency Review Agent · copilot · auto · 51.1 AIC · ⌖ 6.81 AIC · ⊞ 13.9K · ◷

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

Labels

area:provider/anthropic Changes files in the provider / anthropic area area:provider Changes files in the provider area kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure parity-approved Go API consistency review found no parity issues size:small At most 30 changed lines across at most 2 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants