Skip to content

Emit Anthropic thinking blocks from reasoning channel #9

@HXYerror

Description

@HXYerror

Part of #1.

Goal

When upstream returns a reasoning model's reasoning content (either as `/responses` reasoning items or as `/chat/completions` `reasoning_content`), translate it into Anthropic-shape `thinking` content blocks on the `/v1/messages` response. Today the adapter actively suppresses this.

Current state

`src/routes/messages/non-stream-translation.ts:305` literally says:

`// GitHub Copilot doesn't generate thinking blocks, so we don't include them in responses`

That comment is stale — Copilot upstream now does generate reasoning content (via both Responses API and the `reasoning_content` field on chat-completions for o-series/gpt-5).

`thinking_delta` and `signature_delta` types are declared in `src/routes/messages/anthropic-types.ts:145–146` but have no producer anywhere in the codebase (dead code).

Tasks

  • Remove the `:305` comment and produce a `thinking` content block when the upstream response has reasoning content
  • On the `/chat/completions` path: if `choices[0].message.reasoning_content` is present (after Reasoning types & reasoning_effort passthrough in chat-completions #7 lands), emit an Anthropic `thinking` block at the start of `content[]`
  • On the `/responses` path (after Anthropic /v1/messages → Responses API adapter #8 lands): for each `reasoning` output item, emit an Anthropic `thinking` block. Preserve `encrypted_content` in the Anthropic `signature`/`data` field per Anthropic extended-thinking spec
  • Streaming: replace dead `thinking_delta`/`signature_delta` types with real producers (see Streaming reasoning events translation #10 for the streaming half)
  • Update `tests/anthropic-response.test.ts` fixtures to cover the thinking-block emission

Acceptance criteria

  • Claude Code shows a "thinking…" UI when calling a reasoning model through copilot-api
  • Multi-turn round-trip preserves the `encrypted_content` blob through the Anthropic `thinking.signature` field
  • Non-reasoning models still produce a clean `text`/`tool_use`-only response (no spurious empty thinking blocks)

File pointers

  • `src/routes/messages/non-stream-translation.ts:305`
  • `src/routes/messages/anthropic-types.ts:145–146` (dead types to wire up)
  • `src/routes/messages/stream-translation.ts` (streaming half)

Metadata

Metadata

Assignees

No one assigned

    Labels

    anthropicAnthropic Messages API compatibilityreasoningReasoning / thinking / encrypted_content

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions