Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
29 changes: 27 additions & 2 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ whale migrate-config

更多说明见 [docs/configuration.md](docs/configuration.md)。

## 是否支持 Coding Plan?
## 是否支持 Coding Plan / 自定义 API 中转站

支持。Whale 可以通过自定义 API endpoint 连接兼容 `/chat/completions` 的 Coding Plan / 第三方 DeepSeek 接口
支持。Whale 可以通过自定义 API endpoint 连接兼容 `/chat/completions` 的 Coding Plan第三方 DeepSeek 接口或 API 中转站

以阿里云百炼为例,在 `~/.whale/config.toml` 中配置:

Expand All @@ -217,6 +217,21 @@ thinking_enabled = true
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
```

也可以配置第三方 API 中转站(如 tokenshengsheng.com):

```toml
model = "gpt-5.5"
reasoning_effort = "medium"
thinking_enabled = false

[api]
base_url = "https://tokenshengsheng.com/v1"

[permissions]
auto_accept = true
default = "allow"
```

然后配置对应的 API key:

```bash
Expand All @@ -235,6 +250,16 @@ whale setup
- `DEEPSEEK_BASE_URL` 环境变量会覆盖 `~/.whale/config.toml` 里的 `[api].base_url`。
- Whale 当前仍然优先适配 DeepSeek 风格的模型、流式输出、thinking、tool calls 和 prefix-cache 工作流。第三方 endpoint 是否完整可用,取决于服务端兼容程度。

### 非 DeepSeek 模型的工具调用

对于不支持原生 `tools` 参数的模型(如通过中转站接入的 GPT 系列模型),Whale 会自动启用 **Prompt-based 工具调用**:

1. 在消息开头注入独立的工具指令系统提示,引导模型用 JSON 代码块输出工具调用
2. 支持多种 JSON 格式的自动解析,包括标准 `{"tool_call": {...}}` 格式和 `{"command": "..."}`、`{"name": "...", "arguments": {...}}` 等替代格式
3. 工具调用结果会以自然语言形式反馈给模型,确保多轮对话上下文完整

此机制在检测到模型非 DeepSeek/Codex 系列时自动激活,无需手动配置。

---

## Non-goals
Expand Down
46 changes: 46 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,52 @@ fallback_filenames = ["AGENTS.md", ".claude/instructions.md", "CLAUDE.md"]
and `deepseek-v4-pro` get 1,000,000 tokens (1M); other models default to 128K. No
manual configuration is needed.

## Custom API Endpoints and Non-DeepSeek Models

Whale supports connecting to compatible API endpoints by setting `[api].base_url`
in `config.toml`. This includes:

- Third-party DeepSeek-compatible services (e.g., Alibaba Bailian)
- API relay / proxy services (e.g., tokenshengsheng.com)
- Any service that implements the `/chat/completions` endpoint

Example configuration for an API relay:

```toml
model = "gpt-5.5"
reasoning_effort = "medium"
thinking_enabled = false

[api]
base_url = "https://tokenshengsheng.com/v1"

[permissions]
auto_accept = true
default = "allow"
```

When using non-DeepSeek models through an API relay, `thinking_enabled` should
typically be set to `false`, as most third-party models do not support the
DeepSeek thinking protocol.

### Prompt-based Tool Calling

For models that do not support the native `tools` parameter (detected
automatically when the model name does not contain "deepseek" or "codex"),
Whale activates **prompt-based tool calling**:

1. A standalone system message with tool instructions is prepended to every
request, telling the model to output tool calls as JSON code blocks
2. Whale parses multiple JSON formats from the model's text output:
- Standard: `{"tool_call": {"name": "...", "arguments": {...}}}`
- Command-style: `{"command": "..."}`
- Named: `{"name": "...", "arguments": {...}}` or `{"tool": "...", "args": {...}}`
- JSON objects with `path`, `query`, or `pattern` fields
3. Tool results are fed back to the model as natural-language user messages,
preserving full conversational context

This mechanism activates automatically — no manual configuration needed.

## Migrating old config

Whale v0.1.8 and earlier used `preferences.json` and `settings.json`. New
Expand Down
6 changes: 4 additions & 2 deletions internal/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func IsSupportedModel(model string) bool {
return true
}
}
return false
// Allow any model for custom API endpoints
return true
}

func DefaultMemoryFileOrder() []string {
Expand All @@ -57,5 +58,6 @@ func ContextWindowForModel(model string) int {
if IsDeepSeekV4Model(model) {
return DeepSeekV4ContextWindow
}
return DefaultContextWindow
// Use large context window for custom models
return DeepSeekV4ContextWindow
}
Loading