DeepSeek
DeepSeekLLMService streams chat completions from DeepSeek through its OpenAI-compatible API.
Overview
DeepSeek's chat models, with control over their thinking mode.
DeepSeekLLMService: anOpenAILLMServicesubclass with DeepSeek's base URL and default model. It usesDeepSeekLLMAdapter, which adds an emptyreasoning_contentto assistant messages that have none, which DeepSeek requires in thinking mode once a tool call is involved.
Upstream page
Pipecat's documentation for the same service.
Source
packages/deepseek/src/llm.ts and deepseek_adapter.ts.
DeepSeek docs
The chat completion API reference.
Installation
bun add @pipedog/deepseekIt depends on @pipedog/openai, which is installed with it.
import { DeepSeekLLMService } from "@pipedog/deepseek/llm";
import { DeepSeekLLMAdapter } from "@pipedog/deepseek/deepseek_adapter";Prerequisites
- A DeepSeek account and an API key from the DeepSeek platform.
- Pass the key as
apiKey. It is required, and the service never falls back toOPENAI_API_KEY. The examples read it fromDEEPSEEK_API_KEY.
DeepSeekLLMService
Configuration
Prop
Type
The other options (organization, project, defaultHeaders, serviceTier,
retryOnTimeout, retryTimeoutSecs, function calling) are OpenAILLMService's. See
OpenAI.
| Base URL | https://api.deepseek.com/v1 |
| Default model | deepseek-flash |
| Models to try | deepseek-flash. See the provider's catalog for the rest. |
Settings
Runtime-updatable settings, passed as settings: new DeepSeekLLMService.Settings({...})
(DeepSeekLLMSettings). They are OpenAI's settings, with these
defaults:
| Setting | Type | Default | Description |
|---|---|---|---|
model | string | "deepseek-flash" | Model name. |
thinking | DeepSeekThinkingConfig | null | { type: "disabled" } | Thinking mode, sent as thinking in the request body. null leaves it to DeepSeek's default. A plain { type } object is converted. |
Every other setting keeps OpenAI's default. Unset sampling settings are left out of the request, so
the provider's own defaults apply. extra carries provider-specific request fields.
Usage
import { LLMUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { DeepSeekLLMService } from "@pipedog/deepseek/llm";
const llm = new DeepSeekLLMService({
apiKey: process.env.DEEPSEEK_API_KEY ?? "",
settings: new DeepSeekLLMService.Settings({
model: "deepseek-flash",
systemInstruction: "You are a helpful assistant in a voice conversation.",
temperature: 0.7,
}),
});Thinking is off by default, because DeepSeek's V4 models otherwise reason before every answer, which delays the first spoken token. Turn it on with DeepSeekLLMService.ThinkingConfig:
const thinking = new DeepSeekLLMService({
apiKey: process.env.DEEPSEEK_API_KEY ?? "",
settings: new DeepSeekLLMService.Settings({
thinking: new DeepSeekLLMService.ThinkingConfig({ type: "enabled" }),
}),
});Change settings mid-call with an LLMUpdateSettingsFrame. The next completion uses them:
// Queue it on the worker, or push it from a processor upstream of the service.
const update = new LLMUpdateSettingsFrame({
delta: new DeepSeekLLMService.Settings({ temperature: 0.2, maxTokens: 300 }),
});Notes
- Runs a completion for each
LLMContextFrame, between anLLMFullResponseStartFrameand anLLMFullResponseEndFrame, and streams the reply asLLMTextFrames, asOpenAILLMServicedoes. Function calls, token usage metrics andrunInferencework the same way. - "developer" messages are sent as "user" messages, since the API doesn't support that role (
supportsDeveloperRoleisfalse). - Messages go through
DeepSeekLLMAdapter, which adds an emptyreasoning_contentto assistant messages that have none, which DeepSeek requires in thinking mode once a tool call is involved. seed,max_completion_tokensandservice_tierare not sent: DeepSeek doesn't support them.- DeepSeek can't enforce a response schema (
supportsResponseSchemaisfalse), sorunInferenceignoresresponseSchema, with a warning.
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/deepseek/package.json: ✅ means the compat smoke test passes on that runtime.
- The client is the official
openaiJS SDK (through@pipedog/openai), which talks throughfetch. It works on Bun, Node, Deno and Cloudflare Workers. - The deprecated
modelconstructor option is not ported. Usesettings. - Tested against a local OpenAI-compatible mock server, not against DeepSeek itself.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).