Skip to content

fix: accept deepseek in HTTP sessions - #134

Merged
delete-cloud merged 5 commits into
mainfrom
fix/http-deepseek-provider
May 11, 2026
Merged

delete-cloud merged 5 commits into
mainfrom
fix/http-deepseek-provider

Conversation

@delete-cloud

@delete-cloud delete-cloud commented May 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • share the configured provider literal between core config and HTTP session schema
  • allow HTTP /sessions to accept provider=deepseek
  • add a regression test for deepseek-v4-pro session metadata

Validation

  • uv run pytest tests/ui/test_http_server.py -q
  • uv run pytest tests/ui/test_http_server.py tests/core/test_config.py tests/coding_agent/test_cli_pipeline.py -k "deepseek or runtime_provider or invalid_runtime_provider" -q
  • uv run basedpyright --level error src/coding_agent/core/config.py src/coding_agent/ui/schemas.py tests/ui/test_http_server.py
  • uv run ruff format --check src/coding_agent/core/config.py src/coding_agent/ui/schemas.py tests/ui/test_http_server.py
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Accept sessions using the DeepSeek runtime provider and its model.
  • Behavior Changes

    • DeepSeek provider disables Anthropic "thinking" mode for calls.
    • Improved grouping of tool-result messages so adjacent tool outputs appear together.
    • Session creation now loads optional runtime defaults from a local agent config when fields are omitted.
  • Refactor

    • Consolidated provider naming usage for consistency.
  • Documentation

    • Updated remote sandbox production guidance and example image.
  • Tests

    • Added tests covering DeepSeek flows, Anthropic streaming, and tool-result grouping.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 11, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@delete-cloud has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 34 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a0501dd5-34bd-4c76-94bb-8c6f04357892

📥 Commits

Reviewing files that changed from the base of the PR and between abe1bbf and 60acfed.

📒 Files selected for processing (1)
  • coding-agent/docs/remote-sandbox-production.md
📝 Walkthrough

Walkthrough

A module-level ProviderName Literal is added and used by Config.provider and CreateSessionRequest.provider. HTTP server loads agent.toml runtime defaults for session creation. deepseek is wired to disable Anthropic "thinking"; AnthropicProvider forwards thinking to stream and groups adjacent tool_result blocks. Tests, docs, and CLI wording updated.

Changes

Provider type and runtime / Anthropic behavior

Layer / File(s) Summary
Central Type Definition
coding-agent/src/coding_agent/core/config.py
ProviderName Literal type alias is defined, enumerating supported providers.
Config Field Update
coding-agent/src/coding_agent/core/config.py
Config.provider is updated to use ProviderName (default unchanged).
Schema Import and Field Update
coding-agent/src/coding_agent/ui/schemas.py
Import ProviderName and change CreateSessionRequest.provider to `ProviderName
HTTP Server Runtime Defaults
coding-agent/src/coding_agent/ui/http_server.py
Add helpers to load agent.toml defaults and apply provider/model/max_steps fallbacks in create_session.
LLM Plugin Wiring (deepseek)
coding-agent/src/coding_agent/plugins/llm_provider.py
When provider == "deepseek", construct AnthropicProvider(..., thinking={'type':'disabled'}).
AnthropicProvider: init
coding-agent/src/coding_agent/providers/anthropic.py
Accept optional thinking param in __init__ and store on instance.
AnthropicProvider: message conversion
coding-agent/src/coding_agent/providers/anthropic.py
Coalesce adjacent tool role messages into a single converted user message with multiple tool_result blocks.
AnthropicProvider: stream
coding-agent/src/coding_agent/providers/anthropic.py
Forward configured thinking in AsyncAnthropic.messages.stream api kwargs when present.
Anthropic tests
coding-agent/tests/providers/test_anthropic.py
Add tests for grouping adjacent tool results and for streaming honoring thinking mode (empty stream yields DoneEvent).
LLM provider test
coding-agent/tests/coding_agent/plugins/test_llm_provider.py
Add test asserting deepseek-created AnthropicProvider has _thinking == {'type':'disabled'}.
HTTP server session test
coding-agent/tests/ui/test_http_server.py
New test verifying session creation accepts provider="deepseek" with model="deepseek-v4-pro" and session state/GET reflect them.
CLI message update
coding-agent/src/coding_agent/__main__.py, coding-agent/tests/cli/test_remote_client.py
Change messaging to "Remote snapshot" / "archived files" / "deleted entries" and update test expectation.
Docs
coding-agent/docs/remote-sandbox-production.md
Switch example runtime image to python:3.11-slim and add guidance about Docker runtime container and long-running entrypoint (sleep infinity).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I stitched a name for every provider,

One lettered Literal to bind them wiser.
Deepseek sleeps while thinking's turned off,
Messages merge so tool-chatter cuts soft.
Hooray — types neat, tests green, docs aloft.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: enabling DeepSeek provider acceptance in HTTP sessions, which aligns with the core objective to share the provider literal between config and schema.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/http-deepseek-provider

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
coding-agent/src/coding_agent/core/config.py (1)

106-109: 💤 Low value

Consider using consistent api_key check pattern.

The deepseek provider uses not values.get("api_key") while other providers (lines 88, 93, 99-100) use "api_key" not in values. Although both work for this case, using the not in pattern would be more consistent and explicit about checking key presence rather than truthiness.

♻️ Optional consistency improvement
-    if values.get("provider") == "deepseek" and not values.get("api_key"):
+    if values.get("provider") == "deepseek" and "api_key" not in values:
         deepseek_token = os.environ.get("DEEPSEEK_API_KEY")
         if deepseek_token:
             values["api_key"] = deepseek_token
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-agent/src/coding_agent/core/config.py` around lines 106 - 109, Change
the deepseek provider presence check to use the same explicit key-presence
pattern as the other providers: replace the condition `not
values.get("api_key")` with `"api_key" not in values` in the block that checks
`values.get("provider") == "deepseek"`, and keep the rest (reading
os.environ["DEEPSEEK_API_KEY"] into `deepseek_token` and setting
`values["api_key"]`) unchanged so behavior matches the other provider branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@coding-agent/src/coding_agent/core/config.py`:
- Around line 106-109: Change the deepseek provider presence check to use the
same explicit key-presence pattern as the other providers: replace the condition
`not values.get("api_key")` with `"api_key" not in values` in the block that
checks `values.get("provider") == "deepseek"`, and keep the rest (reading
os.environ["DEEPSEEK_API_KEY"] into `deepseek_token` and setting
`values["api_key"]`) unchanged so behavior matches the other provider branches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fb6e6999-6380-4c2a-9ccc-0925fa44781c

📥 Commits

Reviewing files that changed from the base of the PR and between 26c7679 and bdb9843.

📒 Files selected for processing (3)
  • coding-agent/src/coding_agent/core/config.py
  • coding-agent/src/coding_agent/ui/schemas.py
  • coding-agent/tests/ui/test_http_server.py

@delete-cloud

Copy link
Copy Markdown
Owner Author

Review follow-up:

  • Skipped the suggested DeepSeek api_key presence change after verification. tests/core/test_config.py::TestLoadConfig::test_deepseek_uses_deepseek_api_key_when_agent_api_key_is_empty documents that AGENT_API_KEY empty should still fall back to DEEPSEEK_API_KEY; changing to key-presence only breaks that behavior.
  • Added a separate CLI wording fix so workspace downloads describe the manifest as a remote snapshot/archive summary, not a true local diff.

Validation:

  • uv run pytest tests/core/test_config.py -k deepseek -q
  • uv run pytest tests/cli/test_remote_client.py -q
  • uv run basedpyright --level error src/coding_agent/core/config.py src/coding_agent/main.py tests/cli/test_remote_client.py
  • uv run ruff format --check src/coding_agent/core/config.py src/coding_agent/main.py tests/cli/test_remote_client.py
  • git diff --check

@delete-cloud

Copy link
Copy Markdown
Owner Author

Dogfood follow-up completed on PR #134.

Findings from real DeepSeek production smoke:

  • HTTP /sessions now accepts explicit provider=deepseek and model=deepseek-v4-pro.
  • CLI remote run originally still failed because server-side default session creation ignored the explicit serve --config [agent] provider/model and fell back to core defaults.
  • DeepSeek Anthropic-compatible tool loops also failed after tool results because thinking mode requires replaying thinking blocks, and adjacent multiple tool results were emitted as separate user messages.

Fixes pushed:

  • HTTP session creation now uses explicit server config [agent] defaults when request provider/model/max_steps are omitted.
  • DeepSeek Anthropic provider disables thinking mode for stable tool loops.
  • Anthropic message conversion groups adjacent tool results into one user message, matching Anthropic/DeepSeek API requirements.

Dogfood smoke passed:

  • production=true server on local Docker workspace provider
  • model deepseek-v4-pro
  • remote run --repo with yolo approval
  • file_read, file_replace, file_write all streamed
  • downloaded snapshot contained task.txt and result.txt
  • local repo result:
    • task.txt: status initial + status remote
    • result.txt: smoke ok
  • session cleanup completed
  • manual admin cleanup left no remote workspaces

Validation:

  • uv run pytest tests/providers/test_anthropic.py tests/coding_agent/plugins/test_llm_provider.py tests/ui/test_http_server.py tests/cli/test_remote_client.py -q
  • uv run basedpyright --level error src/coding_agent/providers/anthropic.py src/coding_agent/plugins/llm_provider.py src/coding_agent/ui/http_server.py tests/providers/test_anthropic.py tests/coding_agent/plugins/test_llm_provider.py tests/ui/test_http_server.py tests/cli/test_remote_client.py
  • uv run ruff format --check src/coding_agent/providers/anthropic.py src/coding_agent/plugins/llm_provider.py src/coding_agent/ui/http_server.py tests/providers/test_anthropic.py tests/coding_agent/plugins/test_llm_provider.py tests/ui/test_http_server.py tests/cli/test_remote_client.py
  • git diff --check

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
coding-agent/docs/remote-sandbox-production.md (1)

45-46: ⚡ Quick win

Consider documenting runtime image dependency requirements.

The example shifted from a custom coding-agent-runtime image to the standard python:3.11-slim base image, which is clearer for demonstration purposes. However, users may wonder whether python:3.11-slim includes all dependencies required by the coding-agent tools (e.g., for bash_run, file operations, or other tool capabilities), or whether they should build a custom runtime image with additional tooling.

Consider adding a brief note explaining:

  • Whether python:3.11-slim is sufficient for basic agent operations
  • What additional dependencies might be needed for specific tool capabilities
  • When users should build a custom runtime image vs. using a base image
📝 Example clarification to add after line 46
 image = "python:3.11-slim"
 image_allowlist = ["python:3.11-slim"]
+# Note: python:3.11-slim provides a minimal baseline. Depending on your agent's
+# tool usage, you may need a custom image with additional dependencies (e.g.,
+# git, build-essential, language-specific toolchains).
 exec_user = "1000:1000"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@coding-agent/docs/remote-sandbox-production.md` around lines 45 - 46, Add a
short explanatory note after the image lines (image = "python:3.11-slim")
stating whether python:3.11-slim is sufficient for basic agent operations (yes
for pure-Python tools), list common extra dependencies users may need for
specific tool capabilities (bash, shell utilities, git, curl, build-essential,
ffmpeg, imagemagick, etc.), and give guidance on when to build a custom runtime
image versus using the base image (i.e., build a custom image when you need
non-Python system packages, compiled binaries, or faster startup with
preinstalled tooling). Ensure this text appears as a brief bullet or paragraph
immediately following the existing image configuration so readers can quickly
see runtime dependency guidance.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@coding-agent/docs/remote-sandbox-production.md`:
- Around line 45-46: Add a short explanatory note after the image lines (image =
"python:3.11-slim") stating whether python:3.11-slim is sufficient for basic
agent operations (yes for pure-Python tools), list common extra dependencies
users may need for specific tool capabilities (bash, shell utilities, git, curl,
build-essential, ffmpeg, imagemagick, etc.), and give guidance on when to build
a custom runtime image versus using the base image (i.e., build a custom image
when you need non-Python system packages, compiled binaries, or faster startup
with preinstalled tooling). Ensure this text appears as a brief bullet or
paragraph immediately following the existing image configuration so readers can
quickly see runtime dependency guidance.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b3ab6369-4b9e-430c-81e9-5f97aa7a0e90

📥 Commits

Reviewing files that changed from the base of the PR and between bdb9843 and abe1bbf.

📒 Files selected for processing (9)
  • coding-agent/docs/remote-sandbox-production.md
  • coding-agent/src/coding_agent/__main__.py
  • coding-agent/src/coding_agent/plugins/llm_provider.py
  • coding-agent/src/coding_agent/providers/anthropic.py
  • coding-agent/src/coding_agent/ui/http_server.py
  • coding-agent/tests/cli/test_remote_client.py
  • coding-agent/tests/coding_agent/plugins/test_llm_provider.py
  • coding-agent/tests/providers/test_anthropic.py
  • coding-agent/tests/ui/test_http_server.py
✅ Files skipped from review due to trivial changes (2)
  • coding-agent/tests/cli/test_remote_client.py
  • coding-agent/src/coding_agent/main.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • coding-agent/tests/ui/test_http_server.py

@delete-cloud
delete-cloud merged commit e54a564 into main May 11, 2026
1 check passed
@delete-cloud
delete-cloud deleted the fix/http-deepseek-provider branch May 11, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant