Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ https://github.com/user-attachments/assets/c49a21a1-5bf9-4768-a76d-f73c9a03ca87
| Claude 4.6-5 | Official/Amazon Bedrock/UModelVerse | `claude-opus-5` | Text, Image | Text |
| GPT-5.4-5.6 | Official/OpenRouter/UModelVerse | `gpt-5.6-sol` | Text, Image | Text, Embedding |
| Kimi-K2.5/K2.6/K3 | Official/OpenRouter/SiliconFlow | `kimi-k3` | Text, Image | Text |
| DeepSeek V4 | Official/OpenRouter/SiliconFlow | `deepseek-v4-pro` | Text | Text |
| DeepSeek V4 | Official/OpenRouter/SiliconFlow | `deepseek-v4-pro` | Text, Image | Text |
| GLM-5.1-5.3 | Official/OpenRouter/SiliconFlow | `glm-5.3` | Text | Text |
| MiniMax-M3 | Official | `MiniMax-M3` | Text, Image | Text |
| Qwen3.6 | OpenRouter/SiliconFlow/vLLM | `qwen/qwen3.6-35b-a3b` | Text, Image | Text, Embedding |
Expand Down
36 changes: 36 additions & 0 deletions changelog/unreleased/2026-08-21-deepseek-responses-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# DeepSeek moves onto the OpenAI Responses protocol

- **Date:** 2026-08-21
- **Type:** refactor
- **Scope:** `deepseek_v4`, `registry`, `tests`

[中文版](2026-08-21-deepseek-responses-protocol.zh.md)

## What changed

- `DeepSeekV4Client` calls `/responses` instead of `/chat/completions`, reading the
`response.reasoning_text.delta`, `response.output_text.delta`,
`response.function_call_arguments.delta` and `response.completed` events, and rebuilding a
replayed chain of thought as a `reasoning` item whose `content` is `reasoning_text`.
- The two SiliconFlow entries, `deepseek-ai/DeepSeek-V4-Flash` and
`deepseek-ai/DeepSeek-V4-Pro`, moved to the generic `openai-chat` client: SiliconFlow serves
Chat Completions only. The OpenRouter and official entries keep the `deepseek-v4` client.
- The DeepSeek cases in the empty-response, tool-call-argument and unknown-event unit suites
moved to the Responses wire shape, and those first two suites gained a case for the generic
`openai-responses` client alongside it.

## Configuration behavior

| `UniConfig` key | On the wire |
| --- | --- |
| `thinking_level` | `reasoning.effort`, pre-mapped to what DeepSeek settles on: `none` / `low` / `high` / `high` / `high` / `max`. Effort `none` turns thinking off; the Chat Completions `thinking` toggle is ignored on this endpoint |
| `thinking_summary` | left out: the endpoint accepts `summary` but never generates one |
| `max_tokens` | `max_output_tokens` |
| `system_prompt` | `instructions` |
| `temperature` | `UnsupportedParameterError` unless it is `1.0` |
| `tool_choice` | `auto` and `none` only; anything else raises `UnsupportedParameterError` |
| `fast_mode` | `UnsupportedParameterError`: `service_tier` is not supported |
| `prompt_caching` | `ENABLE` only; caching is automatic |

Usage arrives as `input_tokens` with `input_tokens_details.cached_tokens`, and `output_tokens`
with `output_tokens_details.reasoning_tokens`.
35 changes: 35 additions & 0 deletions changelog/unreleased/2026-08-21-deepseek-responses-protocol.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# DeepSeek 改用 OpenAI Responses 协议

- **Date:** 2026-08-21
- **Type:** refactor
- **Scope:** `deepseek_v4`, `registry`, `tests`

[English](2026-08-21-deepseek-responses-protocol.md)

## 变更内容

- `DeepSeekV4Client` 改为调用 `/responses` 而非 `/chat/completions`,解析
`response.reasoning_text.delta`、`response.output_text.delta`、
`response.function_call_arguments.delta` 与 `response.completed` 事件,回放思维链时重建成
`content` 为 `reasoning_text` 的 `reasoning` 条目。
- SiliconFlow 的两个条目 `deepseek-ai/DeepSeek-V4-Flash` 与 `deepseek-ai/DeepSeek-V4-Pro` 改用通用
的 `openai-chat` 客户端:SiliconFlow 只提供 Chat Completions。OpenRouter 与官方条目仍走
`deepseek-v4` 客户端。
- 空响应、工具参数与未知事件三个单测套件里的 DeepSeek 用例改为 Responses 线格式,前两个套件同时
新增了通用 `openai-responses` 客户端的用例。

## 配置映射

| `UniConfig` 键 | 线上字段 |
| --- | --- |
| `thinking_level` | `reasoning.effort`,按 DeepSeek 实际生效的值预先映射:`none` / `low` / `high` / `high` / `high` / `max`。effort 取 `none` 才能关闭思考,Chat Completions 的 `thinking` 开关在该端点上被忽略 |
| `thinking_summary` | 不下发:该端点接受 `summary` 但从不生成 |
| `max_tokens` | `max_output_tokens` |
| `system_prompt` | `instructions` |
| `temperature` | 非 `1.0` 时抛 `UnsupportedParameterError` |
| `tool_choice` | 只接受 `auto` 与 `none`,其余抛 `UnsupportedParameterError` |
| `fast_mode` | 抛 `UnsupportedParameterError`:不支持 `service_tier` |
| `prompt_caching` | 只接受 `ENABLE`,缓存由服务端自动处理 |

用量字段为 `input_tokens`(含 `input_tokens_details.cached_tokens`)与 `output_tokens`
(含 `output_tokens_details.reasoning_tokens`)。
24 changes: 24 additions & 0 deletions changelog/unreleased/2026-08-21-deepseek-vision.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# deepseek-v4-flash-vision-exp reads images, in a prompt and in a tool result

- **Date:** 2026-08-21
- **Type:** feature
- **Scope:** `deepseek_v4`, `registry`, `llmsdk_docs`, `tests`

[中文版](2026-08-21-deepseek-vision.zh.md)

## What changed

- `deepseek-v4-flash-vision-exp` joined the registry on the official API with `Text, Image`
input, a 1M context window, and the `deepseek-v4-flash` price (¥1.5 / ¥4.5 per million
tokens off-peak, ¥0.05 on a cache hit).
- `DeepSeekV4Client` sends an `image_url` item as an `input_image` content part and a
`tool_result` image as an `input_image` inside `function_call_output`, so a tool can hand the
model a picture it produced. Both an HTTP(S) URL and a base64 data URL are accepted.
- A model without vision refuses an image item with
`DeepSeek <model> does not support image inputs.` rather than sending one: Chat Completions
answers `400` and the Responses API silently substitutes placeholder text.
- `deepseek-v4-flash-vision-exp` replaced `deepseek-v4-flash` as the official DeepSeek entry in
both E2E model lists, with image understanding enabled; the three protocol-mode entries stay
on `deepseek-v4-flash`.
- `llmsdk_docs/deepseek_v4/` gained snapshots of the vision and Responses API guides, and its
quickstart lists the third model.
21 changes: 21 additions & 0 deletions changelog/unreleased/2026-08-21-deepseek-vision.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# deepseek-v4-flash-vision-exp 可读图片,提示词与工具返回都支持

- **Date:** 2026-08-21
- **Type:** feature
- **Scope:** `deepseek_v4`, `registry`, `llmsdk_docs`, `tests`

[English](2026-08-21-deepseek-vision.md)

## 变更内容

- 注册表新增官方 API 上的 `deepseek-v4-flash-vision-exp`,输入模态为 `Text, Image`,上下文窗口
1M,价格与 `deepseek-v4-flash` 相同(谷值每百万 token 输入 ¥1.5、输出 ¥4.5,命中缓存 ¥0.05)。
- `DeepSeekV4Client` 把 `image_url` 条目发成 `input_image` 内容块,把 `tool_result` 里的图片发成
`function_call_output` 内的 `input_image`,于是工具可以把自己产出的图片交给模型。HTTP(S) 链接与
base64 data URL 都可用。
- 不带视觉能力的模型遇到图片条目会直接报
`DeepSeek <model> does not support image inputs.` 而不是照发:Chat Completions 会返回 `400`,
Responses API 则会静默替换成占位文本。
- 两份 E2E 模型清单里,官方 DeepSeek 条目由 `deepseek-v4-flash` 换成
`deepseek-v4-flash-vision-exp` 并打开图像理解;三个协议模式条目仍用 `deepseek-v4-flash`。
- `llmsdk_docs/deepseek_v4/` 新增视觉与 Responses API 两份官方文档快照,quickstart 补上第三个模型。
15 changes: 15 additions & 0 deletions changelog/unreleased/2026-08-21-responses-input-order.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Responses input items keep the order the assistant produced them in

- **Date:** 2026-08-21
- **Type:** fix
- **Scope:** `deepseek_v4`, `openai_responses`

[中文版](2026-08-21-responses-input-order.zh.md)

## What changed

- `DeepSeekV4Client` and `OpenaiResponsesClient` flush the message text collected so far
before appending a reasoning, `function_call` or `function_call_output` item, so an assistant
turn that spoke before calling a tool replays as text, then call, then output.
- Before the fix the assistant message was appended after the items it preceded, which DeepSeek
answered with `400 No tool output found for tool call <id>` on the next turn.
15 changes: 15 additions & 0 deletions changelog/unreleased/2026-08-21-responses-input-order.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Responses 输入条目保持助手产出时的顺序

- **Date:** 2026-08-21
- **Type:** fix
- **Scope:** `deepseek_v4`, `openai_responses`

[English](2026-08-21-responses-input-order.md)

## 变更内容

- `DeepSeekV4Client` 与 `OpenaiResponsesClient` 在追加 reasoning、`function_call` 或
`function_call_output` 条目之前,先把已经收集的消息正文落盘,因此「先说话再调工具」的助手轮次
会按正文、调用、结果的顺序回放。
- 修复前助手消息被排到它本应领先的条目之后,DeepSeek 会在下一轮返回
`400 No tool output found for tool call <id>`。
3 changes: 3 additions & 0 deletions changelog/unreleased/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@

[中文版](README.zh.md)

- [2026-08-21] `deepseek-v4-flash-vision-exp` reads images, in a prompt and in a tool result. ([details](2026-08-21-deepseek-vision.md))
- [2026-08-21] DeepSeek moves onto the OpenAI Responses protocol. ([details](2026-08-21-deepseek-responses-protocol.md))
- [2026-08-21] Responses input items keep the order the assistant produced them in. ([details](2026-08-21-responses-input-order.md))
- [2026-08-21] The playground remembers its configuration across a reload. ([details](2026-08-21-playground-config-memory.md), [#184](https://github.com/Prism-Shadow/agenthub/pull/184))
- [2026-08-20] Gemini TTS requests carry a single text turn, and the playground plays one audio clip. ([details](2026-08-20-gemini-tts-single-turn.md), [#184](https://github.com/Prism-Shadow/agenthub/pull/184))
3 changes: 3 additions & 0 deletions changelog/unreleased/README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@

[English](README.md)

- [2026-08-21] `deepseek-v4-flash-vision-exp` 可读图片,提示词与工具返回都支持。([详情](2026-08-21-deepseek-vision.zh.md))
- [2026-08-21] DeepSeek 改用 OpenAI Responses 协议。([详情](2026-08-21-deepseek-responses-protocol.zh.md))
- [2026-08-21] Responses 输入条目保持助手产出时的顺序。([详情](2026-08-21-responses-input-order.zh.md))
- [2026-08-21] Playground 刷新后保留配置。([详情](2026-08-21-playground-config-memory.zh.md), [#184](https://github.com/Prism-Shadow/agenthub/pull/184))
- [2026-08-20] Gemini TTS 请求只带一轮文本,Playground 播放单条音频。([详情](2026-08-20-gemini-tts-single-turn.zh.md), [#184](https://github.com/Prism-Shadow/agenthub/pull/184))
2 changes: 2 additions & 0 deletions llmsdk_docs/deepseek_v4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ This directory contains documentation for using the DeepSeek API with OpenAI-com
The `docs/` folder contains focused guides for DeepSeek API features:

- [chat_completion_api.md](./docs/chat_completion_api.md) - DeepSeek Chat Completion API reference
- [responses-api.md](./docs/responses-api.md) - Responses API support: streaming events, image input, parameter and input-item coverage
- [kv-cache.md](./docs/kv-cache.md) - Default context caching, hit rules, and usage counters
- [multi-round-chat.md](./docs/multi-round-chat.md) - Stateless multi-turn conversation history
- [vision.md](./docs/vision.md) - Image input on deepseek-v4-flash-vision-exp across the three API formats, with detail levels and limits
- [thinking-mode.md](./docs/thinking-mode.md) - Thinking mode, reasoning content, effort control, and tool-call context rules
- [tool-calls.md](./docs/tool-calls.md) - Tool calling, thinking-mode tool calls, and strict mode

Expand Down
156 changes: 156 additions & 0 deletions llmsdk_docs/deepseek_v4/docs/responses-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Using the Responses API

> Source: https://api-docs.deepseek.com/guides/responses_api (snapshot 2026-08-21)

DeepSeek serves the OpenAI Responses API format at base URL `https://api.deepseek.com`, so the
OpenAI SDK reaches it with only a base URL and API key change.

## Basic Usage

```python
from openai import OpenAI

client = OpenAI(api_key="<your DeepSeek API Key>", base_url="https://api.deepseek.com")
response = client.responses.create(
model="deepseek-v4-flash",
instructions="You are a helpful assistant.",
input="Hi, how are you?",
)
print(response.output_text)
```

## Streaming

Set `stream: true` to receive server-sent events. Each event carries a `type` and a monotonically
increasing sequence number, and the stream ends with a terminal event rather than `data: [DONE]`.

```python
stream = client.responses.create(
model="deepseek-v4-flash",
instructions="You are a helpful assistant.",
input="Hi, how are you?",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="")
```

| Event | Purpose |
| --- | --- |
| `response.created` | Initial event; status is `in_progress` |
| `response.in_progress` | Response generation ongoing |
| `response.output_item.added` / `response.output_item.done` | Output item lifecycle (reasoning, message, function_call, ...) |
| `response.content_part.added` / `response.content_part.done` | Content part lifecycle within an item |
| `response.reasoning_text.delta` / `response.reasoning_text.done` | Chain-of-thought incremental / complete |
| `response.output_text.delta` / `response.output_text.done` | Output text incremental / complete |
| `response.function_call_arguments.delta` / `response.function_call_arguments.done` | Function arguments incremental / complete |
| `response.custom_tool_call_input.delta` / `response.custom_tool_call_input.done` | Custom tool input incremental / complete |
| `response.web_search_call.in_progress` / `.searching` / `.completed` | Web search status |
| `response.completed` | Normal completion, with the full response object |
| `response.incomplete` | Truncation (for example `max_output_tokens` reached) |
| `response.failed` | Failure, with error details |

## Image Input

`deepseek-v4-flash-vision-exp` accepts images as `input_image` content parts:

```python
response = client.responses.create(
model="deepseek-v4-flash-vision-exp",
input=[
{
"role": "user",
"content": [
{"type": "input_text", "text": "What is in this image?"},
{"type": "input_image", "image_url": "https://example.com/image.jpg", "detail": "low"},
],
}
],
)
print(response.output_text)
```

Images may also ride in `function_call_output` and `custom_tool_call_output`, so a tool can hand
the model an image it produced.

### `input_image` fields

- `image_url`: an HTTP(S) URL (max 8192 characters) or a base64 data URL. JPEG, PNG, GIF and WebP.
- `file_id`: an image id from the Files API (`file-api-...`).
- `detail`: `low` / `high` / `original` / `auto`. `low` downsamples to 512x512; the others keep the
original size. Ignored when `file_id` is set.

`image_url` and `file_id` are mutually exclusive: passing both, or neither, returns `400`.

### Image restrictions

- Images are allowed only in `user` / `developer` messages and in `function_call_output` /
`custom_tool_call_output`. An image in a `system` or `assistant` message returns `400`.
- Only vision models read `input_image` parts; other models replace them with placeholder text.
- Limits: 32 MiB per inline image, 64 MiB per `file_id` image, 64 MiB total inline (up to 200 MiB
with `file_id`), and 600 images per request.

## Top-level request parameters

| Parameter | Status | Notes |
| --- | --- | --- |
| `model` | Supported | `deepseek-v4-flash` / `deepseek-v4-pro` / `deepseek-v4-flash-vision-exp` |
| `input` | Supported | String or input item list; `input` or `instructions` is required |
| `instructions` | Supported | Inserted as the first system message |
| `stream` | Supported | — |
| `temperature` | Supported | Range [0.0, 2.0]; no effect in thinking mode |
| `top_p` | Supported | No effect in thinking mode |
| `max_output_tokens` | Supported | — |
| `top_logprobs` | Supported | Range [0, 20] |
| `tools` | Partially supported | `function` / `web_search` supported; other types ignored |
| `tool_choice` | Supported | `none` / `auto` / `required` / a specific tool |
| `reasoning` | Partially supported | `effort` supported; `summary` accepted but never generated |
| `text` | Partially supported | `format` supported; `verbosity` has no effect |
| `user` | Supported | See Rate Limit & Isolation |
| `parallel_tool_calls` | Ignored | Always enabled |
| `max_tool_calls` | Ignored | — |
| `previous_response_id` | Not supported | Stateless API |
| `conversation` | Not supported | Stateless API |
| `store` | Not supported | Always `store: false` |
| `background` | Not supported | — |
| `metadata` | Not supported | — |
| `include` | Not supported | — |
| `prompt` | Not supported | — |
| `truncation` | Not supported | Exceeding the context window returns `400` |
| `service_tier` | Not supported | — |
| `safety_identifier` | Not supported | — |
| `prompt_cache_key` / `prompt_cache_retention` | Not supported | Context caching is automatic |
| `context_management` | Not supported | — |
| `stream_options` | Not supported | — |

Unsupported parameters are silently ignored rather than rejected.

## Input item types

| Type | Status | Notes |
| --- | --- | --- |
| `message` | Supported | Roles `user` / `assistant` / `system` / `developer` (developer is treated as user); content takes a string or `input_text` / `output_text` / `input_image` parts. The vision model reads images; other models substitute a placeholder. File inputs are unsupported |
| `function_call` | Supported | Merged into the adjacent assistant message |
| `function_call_output` | Supported | `output` takes a string or a content part list; `input_image` parts are read as real images by the vision model |
| `reasoning` | Supported | Plain-text content is merged into the assistant message; `summary` and `encrypted_content` are unsupported |
| `web_search_call` | Supported | Passed back as-is; the server restores its results |
| `custom_tool_call` / `custom_tool_call_output` | Supported | Only the `apply_patch` tool; images in the output are read by the vision model |
| Other types | Ignored | — |

## Tools

| Type | Status | Notes |
| --- | --- | --- |
| `function` | Supported | — |
| `web_search` / `web_search_2025_08_26` | Supported | Executed server-side; `search_context_size` and `user_location` are ignored; auto-continuation is capped at 10 rounds |
| `custom` | Partially supported | Only `{"type": "custom", "name": "apply_patch"}`; another name returns `400` |
| `file_search` / `code_interpreter` / `computer_use` / `mcp` / other built-ins | Ignored | — |

## Response fields and token usage

The response object matches the OpenAI Responses API structure; unsupported capabilities come back
as fixed values (`store: false`, `previous_response_id: null`, `parallel_tool_calls: true`).

- `input_tokens`, with `input_tokens_details.cached_tokens` for context cache hits.
- `output_tokens`, with `output_tokens_details.reasoning_tokens` for chain-of-thought tokens.
Loading
Loading