Files
93b0fd229c Release 0.2.0
Co-authored-by: xinchengxx <xinchengxx@deepseek.com>
Co-authored-by: zhu-he <hezhu@deepseek.com>
2026-10-20 00:21:22 +08:00

16 KiB

Changelog

This file lists the changes to the Rust crates and to the deepseek-recipe Python distribution. All crates and the distribution share one version. The format follows Keep a Changelog, and versions follow Semantic Versioning: before 1.0, a new minor version can contain incompatible changes.

Unreleased

0.2.0 - 2026-10-20

This release changes the public API of every crate and of the Python package. Migrating from 0.1 lists the renamed and removed items.

Added

  • Model versions. Conversion resolves a ModelVersion (V4 or V4.1) from the request's model name through ConversionOptions::model_versions_by_name. The defaults are DeepSeek-V4-Pro and DeepSeek-V4.1-Flash; with_model_alias and with_model_versions_by_name register other names. ConversationRequest::model_version reports the result. V4 does not accept images (ModelVersion::supports_image): conversion replaces each image of a V4 request with the text [Unsupported Image]. Python: ConversionOptions.model_versions_by_name, with_model_alias, and with_model_versions_by_name.
  • Sampling values by model version. Conversion resolves temperature and top_p instead of passing them through. temperature is 1.0 in thinking mode and otherwise the requested value or 1.0. top_p follows ModelVersion::resolve_top_p: in thinking mode, V4.1 raises it to at least 0.95, and V4 uses 0.95 with tools and 1.0 without; outside thinking mode, V4.1 uses 1.0 and V4 uses the requested value.
  • Log probabilities. Conversion maps Chat Completions logprobs and top_logprobs, and Responses top_logprobs, into InferenceOptions. The caller supplies backend values in InferenceChunk::Tokens, and the Chat Completions and Responses adapters report them. OutputChunk::Content and OutputChunk::Reasoning carry them as logprobs.
  • Reasoning token counts. CompletionUsage::reasoning_tokens: in thinking mode, a stream processor with an attached tokenizer counts the tokens of the reasoning content, and Chat Completions and Responses report them.
  • Structured output. ResponseFormat::JsonSchema and ResponseFormat::Regex. Conversion validates a Chat Completions response_format or Responses text.format of type json_schema, which 0.1 accepted and ignored, and rendering writes the schema into the prompt. A Chat Completions regex response format passes through as ResponseFormat::Regex.
  • Explicit special tokens. The new deepseek-recipe-macros crate provides the prompt! macro, and deepseek-recipe-core provides Prompt. RenderedPrompt::special_ranges records the byte ranges of the explicit special tokens, and PromptTokenizer encodes only those ranges as special tokens. Apart from the grounding tokens in assistant content and reasoning content, a special-token spelling in message text encodes as plain text.
  • Prefix continuation. A final Chat Completions assistant message with prefix: true continues that message instead of starting a new assistant turn. InputMessage::Assistant gains prefix. Python: the prefix argument of AssistantMessage.
  • Deferred tool loading and tool search. V4.1 supports deferred tool loading in Messages and client-executed tool_search in Responses. ToolDefinition gains defer_loading, and InputMessage::System gains tools. Python: ToolDefinition.defer_loading and SystemMessage.tools.
  • System images. V4.1 accepts images in system messages. InputMessage::System gains image_sources. Python: the image_sources and image_token arguments of SystemMessage.
  • Image destination filtering. DestinationFilter and ReqwestImageFetcher::with_destination_filter check the URL host, every resolved address, and every redirect target. A rejected destination fails with ImageError::DestinationRejected. Python: ReqwestImageFetcher.with_destination_filter.
  • Request settings in responses. Conversion preserves usage inclusion, tool output types, namespace mappings, and echoed request settings in ConversationRequest::response_options. ProtocolRequest::chunk_generator applies them when constructing a generator. Python: the request types' chunk_generator methods.
  • Max tokens upper bounds. ConversionOptions::thinking_max_tokens_upper_bound and ConversionOptions::non_thinking_max_tokens_upper_bound, set by the matching with_* methods: the largest accepted max_tokens in thinking mode and outside it, both defaulting to DEFAULT_MAX_TOKENS_UPPER_BOUND (393216). resolve_max_tokens_upper_bound selects the bound of a request's thinking mode; Messages lowers a larger value to it, Chat Completions and Responses reject it. Python: the matching keywords, properties, and with_* methods of ConversionOptions.
  • Output constraints. InferenceOptions::output_constraint holds the OutputConstraint that constrained decoding would enforce. A request with tools and a tool choice other than none gets ToolCalls, which lists the tools and whether a call is required. Otherwise a JSON object or JSON Schema response format gets Json, and a regex response format gets Regex. OutputConstraint::kind returns json, regex, tool_call, or tool_call_required, and OutputConstraint::schema returns the constraint text. Whether the backend applies the constraint is the caller's decision. Python: OutputConstraint and InferenceOptions.output_constraint.
  • ConversationRequest::resolve_max_tokens: after the caller encodes the prompt, it resolves the max_tokens to send from the prompt's token count and a caller-supplied context limit. A request without max_tokens gets 8192 outside thinking mode, 65536 in thinking mode, and 131072 in thinking mode with max effort (DEFAULT_NON_THINKING_MAX_TOKENS, DEFAULT_THINKING_MAX_TOKENS, DEFAULT_MAX_EFFORT_MAX_TOKENS), lowered to the context left after the prompt. When the prompt and the requested max_tokens together exceed the context limit, it returns a 400 Bad Request error whose message matches the DeepSeek API: This model's maximum context length is {context_limit} tokens. .... Python: ConversationRequest.resolve_max_tokens.
  • SpecialToken names the grounding tokens (Ref, RefEnd, Box, BoxEnd, Point, PointEnd, Polygon, PolygonEnd), so a SpecialTokens mapping can respell them; SpecialTokensMap has a field for each. The encoding crate lists them as the assistant special tokens that rendering inserts from assistant content and reasoning content. Python: the matching SpecialToken members and SpecialTokens keywords.
  • deepseek_recipe_core::multimodal::UNSUPPORTED_IMAGE_ERROR_MESSAGE: the text of the unsupported-image error.
  • Shared request types RequestReasoningEffort and ThinkingType.
  • Request schema types: MessagesMetadata validates metadata, MessagesTool distinguishes client tools from server tools (MessagesServerTool), and ResponsesWebSearchTool deserializes and validates the search_context_size and user_location of a web_search or web_search_2025_08_26 tool.
  • Python: the ModelVersion enum, a ResponsesEcho constructor with read-only getters, the response_schema and response_regex arguments of Conversation, the image_token argument of UserMessage and ToolMessage, an optional tool_call_id of ToolMessage, and the model property of the protocol requests, readable before convert.

Changed

  • Conversion rejects a request whose model is not a key of ConversionOptions::model_versions_by_name. Register any additional name, such as deepseek-flash, with with_model_alias.
  • Validation error messages and the order of the checks match the DeepSeek API.
  • A Responses reasoning item without text adds nothing to the conversation; encrypted_content is accepted and ignored.
  • V4.1 preserves Messages system and Responses developer messages as system messages.
  • Messages document blocks require a source object. Their unsupported-content text includes the media type.
  • A complete Chat Completions response numbers its tool_calls with index (ChatCompletionIndexedToolCall), as the streamed deltas do.
  • StreamProcessor::with_tokenizer takes a StreamTokenizer. Besides decode_ids, the trait has the optional methods id_to_token, for log probabilities, count_tokens, for reasoning token counts, and is_special_token, for marker matching.
  • PromptTokenizer encodes the plain text regions of a prompt as one batch through Tokenizer::encode_batch_fast instead of one region at a time. The tokenizers crate encodes the batch in parallel unless its TOKENIZERS_PARALLELISM environment variable disables parallelism.
  • Conversion rejects a request that mixes strict and non-strict tools, and a request that sets a response format together with strict tools, unless the tool choice is none.
  • With token input, the stream processor decodes each special token as its own piece. Output parsing matches the thinking end token (</think> by default) and the DSML token within DSML tags only against decoded special tokens; the same text spelled with plain tokens is content. The log probabilities of these special tokens are reported with the marker rather than with the surrounding content. Text chunks still match markers by spelling.
  • The Python distribution takes its version from the Cargo package, so deepseek_recipe.__version__ matches the installed distribution.

Removed

  • InferenceChunk::Token. Send one InferenceChunk::Tokens chunk instead.
  • The arguments field of OutputChunk::ToolCall, now ToolCallNamed. Arguments arrive in ToolCallArgumentsDelta chunks.
  • The util modules of deepseek-recipe and deepseek-recipe-core, and the public state_machine module and StreamDecoder type of deepseek-recipe. Output parsing and token decoding are internal to StreamProcessor; ParsingOptions and ThinkingInitialStage remain public in stream.
  • The per-protocol reasoning effort and thinking type enums, replaced by RequestReasoningEffort and ThinkingType.
  • MessagesContentBlock::ToolReference. A Messages request can contain a tool reference only in tool_result.content or tool_addition.tool.
  • Public constructors of ChatCompletionChunkGenerator and ResponsesChunkGenerator. Use ProtocolRequest::chunk_generator with a converted request. Python: use the request type's chunk_generator method.
  • ChatCompletionRequest::include_usage, ChatCompletionChunkGenerator::with_include_usage, ResponsesRequest::custom_tool_names, and ResponsesChunkGenerator::with_custom_tool_names, including their Python equivalents.
  • InferenceOptions::thinking_budget_tokens and InferenceOptions::disable_parallel_tool_use. Conversion accepts and ignores Messages thinking.budget_tokens and disable_parallel_tool_use and Chat Completions parallel_tool_calls, as the DeepSeek API does. Python: the thinking_budget_tokens and disable_parallel_tool_use properties of InferenceOptions.
  • Python: InferenceChunk.token() and InferenceChunk.token_id.

Migrating from 0.1

Rust

0.1 0.2
ConversationRequest::new(conversation) ConversationRequest::new(conversation, model_version)
ConversationRequest::model ConversationRequest::model_version; the model name stays on the protocol request
ChatCompletionChunkGenerator::new(...), ResponsesChunkGenerator::new(...) ChatCompletionRequest::chunk_generator(&converted, id, model), ResponsesRequest::chunk_generator(&converted, id, model)
ConversionError::into_response ConversionError::into_error_response
StreamProcessor::process StreamProcessor::into_protocol_stream
TokenizerDecoder StreamTokenizer
InferenceChunk::Text { content, content_tokens } InferenceChunk::Text { content, token_count }
InferenceChunk::Token { token_id } InferenceChunk::Tokens { token_ids: vec![token_id], logprobs: None }
OutputChunk::Start { usage } OutputChunk::Start { prompt_usage }
OutputChunk::Raw { content } OutputChunk::Content { content, logprobs }
OutputChunk::Reasoning { content } OutputChunk::Reasoning { content, logprobs }
OutputChunk::ToolCall { tool_name, arguments } OutputChunk::ToolCallNamed { tool_name }
OutputChunk::ToolArgumentsDelta { content } OutputChunk::ToolCallArgumentsDelta { arguments }
OutputChunk::Finish { reason, usage, .. } OutputChunk::Finish { finish_reason, completion_usage, .. }
ParsingOptions::reasoning_initial_stage: Option<ReasoningStage> ParsingOptions::thinking_initial_stage: Option<ThinkingInitialStage>
ParsingOptions::tool_call_initial_stage ParsingOptions::starts_in_tool_calls
ReasoningStage::start_from_reasoning ThinkingInitialStage::starts_in_reasoning
ReasoningContentBehavior::Ignore ReasoningContentBehavior::FillEmpty
WebSearchBehavior::Ignore WebSearchBehavior::Drop
util::append_delta::AppendDelta response::Accumulate
util::json_formatter deepseek_recipe_core::json
ImageTokenSpec::calc_token_len ImageTokenSpec::calc_token_count
ImageTokenSpec::max_n_token ImageTokenSpec::max_token_count
MessagesReasoningEffort, ChatCompletionReasoningEffort, ResponsesReasoningEffort RequestReasoningEffort
MessagesThinkingType, ChatCompletionThinkingType ThinkingType
MessagesTextOrTextBlocks, MessagesTextBlock MessagesSystemContent, MessagesSystemBlock
MessagesTool { name, description, input_schema, kind } MessagesTool::Client { name, description, input_schema, defer_loading }, MessagesTool::Server(MessagesServerTool)
MessagesResponseContent, MessagesDelta, MessagesStopInfo MessagesResponseContentBlock, MessagesContentBlockDelta, MessagesMessageDelta
ChatCompletionToolChoiceMode, ChatCompletionNamedToolChoice variants of ChatCompletionToolChoiceOption
ResponsesToolChoiceMode variants of ResponsesToolChoice

Python

0.1 0.2
ConversationRequest(conversation) ConversationRequest(conversation, model_version)
ConversationRequest.model ConversationRequest.model_version; read the name from the protocol request's model before convert
ChatCompletionChunkGenerator(...), ResponsesChunkGenerator(...) ChatCompletionRequest.chunk_generator(converted, id, model), ResponsesRequest.chunk_generator(converted, id, model)
*Response.append(chunk) *Response.accumulate(chunk)
*Response.chunk_event_type(chunk) *Response.sse_event_name(chunk)
*Response.done_message() *Response.sse_done_data()
InferenceChunk.text(text, content_tokens) InferenceChunk.text(content, token_count)
InferenceChunk.content_tokens InferenceChunk.token_count
InferenceChunk.token(token_id) InferenceChunk.tokens([token_id])
ReasoningStage ThinkingInitialStage
ReasoningStage.start_from_reasoning ThinkingInitialStage.starts_in_reasoning
model version strings such as "DeepSeek-V4-Pro" ModelVersion.DeepseekV4Pro, ModelVersion.DeepseekV41Flash

0.1.0 - 2026-09-10

Initial release: conversion of Messages, Chat Completions, and Responses requests into a shared conversation, DeepSeek V4 and V4.1 prompt rendering, image fetching and preprocessing, streaming output parsing into protocol responses, and the deepseek-recipe Python distribution.