pi-deepseek-web-search 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zzwtsy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # pi-deepseek-web-search
2
+
3
+ A [pi](https://github.com/earendil-works/pi) extension that gives any model in your pi sessions a **DeepSeek-backed web search** tool, bridging the DeepSeek `/responses` API server-side web search.
4
+
5
+ [中文说明](README.zh.md)
6
+
7
+ ## Features
8
+
9
+ - **Forced search** — every call executes a real web search (`tool_choice: { type: "web_search" }`); the model cannot skip it
10
+ - **Synthesized answer with citations** returned by DeepSeek, plus a record of the executed search actions
11
+ - **Configurable** via env vars, project config file, or global config file (in that order of precedence)
12
+ - **TTL result cache** — repeated identical queries within the TTL hit the cache and cost nothing
13
+ - **Real cost reporting** — token prices are configurable (CNY per million tokens) with future peak-hour pricing support, and the reported `Usage.cost` reflects the actual estimated spend
14
+ - **Model selectable** — `deepseek-v4-flash` (default) now; switch to `deepseek-v4-pro` by config once it supports the Responses API
15
+ - **Generated JSON Schema** — the config file definition is a single source of truth (`src/config-schema.ts`); English and Chinese schemas are generated from it (see [Schema](#schema))
16
+
17
+ ## Install
18
+
19
+ From the project root of this package:
20
+
21
+ ```bash
22
+ pi install .
23
+ ```
24
+
25
+ Or symlink/copy `src/index.ts` into your project's `.pi/extensions/` and run `/reload` in the pi session.
26
+
27
+ ## Configuration
28
+
29
+ Config is read from, in order of precedence (later sources override earlier ones):
30
+
31
+ 1. Environment variables
32
+ 2. Project config file: `.pi/deepseek-web-search.json`
33
+ 3. Global config file: `~/.pi/agent/deepseek-web-search.json`
34
+
35
+ ### Example (`.pi/deepseek-web-search.json`)
36
+
37
+ ```jsonc
38
+ {
39
+ "$schema": "../schema/deepseek-web-search.config.schema.en.json",
40
+ "apiKey": "sk-...",
41
+ "model": "deepseek-v4-flash",
42
+ "reasoningEffort": "low",
43
+ "prices": {
44
+ "inputPerMillion": 1,
45
+ "cachedInputPerMillion": 0.02,
46
+ "outputPerMillion": 2
47
+ }
48
+ }
49
+ ```
50
+
51
+ > `$schema` is only used by editors for autocomplete/validation and is ignored at runtime. Use the `.en.json` schema for English comments, or the `.zh.json` one for Chinese.
52
+
53
+ ### Config fields
54
+
55
+ | Field | Type | Default | Description |
56
+ | ----- | ---- | ------- | ----------- |
57
+ | `apiKey` | string | — | DeepSeek API key (required). `DEEPSEEK_API_KEY` overrides |
58
+ | `baseUrl` | string | `https://api.deepseek.com` | API base URL (change when using a proxy) |
59
+ | `model` | string | `deepseek-v4-flash` | Model name. `DEEPSEEK_MODEL` overrides |
60
+ | `reasoningEffort` | `off`/`low`/`high`/`auto` | `low` | `off` disables thinking to save tokens |
61
+ | `maxOutputTokens` | int ≥ 1 | `4096` | Max output tokens |
62
+ | `timeoutMs` | int ≥ 1 | `30000` | Request timeout in ms |
63
+ | `cacheTtlMs` | int ≥ 1 | `300000` | Result cache TTL in ms |
64
+ | `maxResultChars` | int ≥ 1 | `50000` | Max chars of the answer returned to the model |
65
+ | `prices.inputPerMillion` | number > 0 | `1` | Input price, cache miss (CNY / 1M tokens) |
66
+ | `prices.cachedInputPerMillion` | number > 0 | `0.02` | Input price, cache hit |
67
+ | `prices.outputPerMillion` | number > 0 | `2` | Output price |
68
+ | `prices.peak` | object | — | Peak-hour pricing override (optional, see below) |
69
+ | `prices.models` | object | — | Per-model price overrides keyed by model name |
70
+
71
+ Environment variable equivalents: `DEEPSEEK_API_KEY`, `DEEPSEEK_BASE_URL`, `DEEPSEEK_MODEL`, `DEEPSEEK_REASONING_EFFORT`, `DEEPSEEK_MAX_OUTPUT_TOKENS`, `DEEPSEEK_TIMEOUT_MS`, `DEEPSEEK_CACHE_TTL_MS`, `DEEPSEEK_MAX_RESULT_CHARS`, `DEEPSEEK_PRICE_INPUT`, `DEEPSEEK_PRICE_CACHED_INPUT`, `DEEPSEEK_PRICE_OUTPUT`.
72
+
73
+ ### Pricing and peak hours
74
+
75
+ Default prices follow the [official DeepSeek pricing page](https://api-docs.deepseek.com/zh-cn/quick_start/pricing) (deepseek-v4-flash: 1 / 0.02 / 2 CNY per million tokens). Pricing is configurable, and a peak-hour override is already supported:
76
+
77
+ ```jsonc
78
+ "prices": {
79
+ "peak": {
80
+ "multiplier": 2,
81
+ "hours": [["09:00", "12:00"], ["14:00", "18:00"]] // half-open [start, end)
82
+ }
83
+ }
84
+ ```
85
+
86
+ - Peak hours follow the official definition: **daily, Beijing time** 09:00–12:00 and 14:00–18:00 (the pricing scheme is *pending* official rollout — omit `peak` until then)
87
+ - Peak price = base × `multiplier`, applied to all billing items
88
+ - Per-model overrides: `prices.models."deepseek-v4-pro" = { "inputPerMillion": 3, "cachedInputPerMillion": 0.025, "outputPerMillion": 6 }` — used automatically when `model` is set to that model
89
+ - The `Usage.cost` reported by the tool reflects the computed estimate; cached hits report no cost (no API call happened)
90
+
91
+ ### Model support
92
+
93
+ The Responses API currently supports only `deepseek-v4-flash`; `deepseek-v4-pro` support is expected in early August 2026. Set `"model": "deepseek-v4-pro"` (or `DEEPSEEK_MODEL`) once it is available — prices switch automatically via `prices.models`.
94
+
95
+ ## Usage
96
+
97
+ Ask the model a time-sensitive or external question; it will invoke `deepseek_web_search` automatically:
98
+
99
+ > What is the weather in Beijing today?
100
+
101
+ The tool returns DeepSeek's synthesized answer with citations plus the executed search actions. Results are cached per `model:mode:query` for `cacheTtlMs`.
102
+
103
+ The `/deepseek-search` command shows config status (key configured, model, cache size) and can clear the cache.
104
+
105
+ ## Schema
106
+
107
+ The config file definition is maintained **once** in `src/config-schema.ts` (TypeBox) and everything else is derived:
108
+
109
+ - `ConfigFileShape` type (via `Static<>`)
110
+ - Runtime validation (via `Check`/`Errors`)
111
+ - Two generated JSON Schema files:
112
+ - `schema/deepseek-web-search.config.schema.en.json` (English comments)
113
+ - `schema/deepseek-web-search.config.schema.zh.json` (Chinese comments)
114
+
115
+ Regenerate after changing the definition:
116
+
117
+ ```bash
118
+ pnpm gen:schema
119
+ ```
120
+
121
+ Generated files are committed and a test asserts they stay in sync with the definition.
122
+
123
+ ## Development
124
+
125
+ ```bash
126
+ pnpm check # tsc --noEmit
127
+ pnpm lint # eslint
128
+ pnpm test # vitest
129
+ pnpm gen:schema
130
+ ```
131
+
132
+ ## FAQ
133
+
134
+ - **Why not the built-in web search tool?** This tool is useful when you want search backed by the DeepSeek API (e.g., to reuse an existing DeepSeek account/balance, or when the session model lacks a built-in search).
135
+ - **Does it return a list of sources?** DeepSeek's search runs server-side; the answer contains inline citations, and the tool additionally records the executed search actions (`searched:`/`opened:` lines) in the returned content.
136
+ - **How much does it cost?** DeepSeek charges per token; the tool reports an estimated `Usage.cost` based on your configured prices. See the [official pricing page](https://api-docs.deepseek.com/zh-cn/quick_start/pricing).
137
+ - **I get an "API key is not configured" error** — set `DEEPSEEK_API_KEY` or add `apiKey` to the config file.
package/README.zh.md ADDED
@@ -0,0 +1,137 @@
1
+ # pi-deepseek-web-search
2
+
3
+ 一个 [pi](https://github.com/earendil-works/pi) 扩展:为 pi 会话中的任意模型提供 **DeepSeek 联网搜索** 能力,桥接 DeepSeek `/responses` API 的服务端搜索。
4
+
5
+ [English](README.md)
6
+
7
+ ## 功能特性
8
+
9
+ - **强制搜索**——每次调用都真实执行搜索(`tool_choice: { type: "web_search" }`),模型无法跳过
10
+ - **综合回答 + 引用**——由 DeepSeek 生成带引用的回答,同时返回执行的搜索动作记录
11
+ - **配置灵活**——环境变量 / 项目配置文件 / 全局配置文件(优先级从高到低)
12
+ - **TTL 结果缓存**——TTL 内相同查询直接命中缓存,零成本
13
+ - **真实成本上报**——token 单价可配置(元/百万 tokens),并前瞻支持峰谷定价;工具上报的 `Usage.cost` 为真实估算金额
14
+ - **模型可选**——默认 `deepseek-v4-flash`;`deepseek-v4-pro` 适配 Responses API 后改配置即切换
15
+ - **生成式 JSON Schema**——配置文件定义单一来源(`src/config-schema.ts`),中/英两份 Schema 由它自动生成(见 [Schema](#schema))
16
+
17
+ ## 安装
18
+
19
+ 在包根目录:
20
+
21
+ ```bash
22
+ pi install .
23
+ ```
24
+
25
+ 或将 `src/index.ts` 软链/复制到项目的 `.pi/extensions/`,在 pi 会话中执行 `/reload`。
26
+
27
+ ## 配置
28
+
29
+ 配置按以下优先级读取(后者覆盖前者):
30
+
31
+ 1. 环境变量
32
+ 2. 项目配置文件:`.pi/deepseek-web-search.json`
33
+ 3. 全局配置文件:`~/.pi/agent/deepseek-web-search.json`
34
+
35
+ ### 示例(`.pi/deepseek-web-search.json`)
36
+
37
+ ```jsonc
38
+ {
39
+ "$schema": "../schema/deepseek-web-search.config.schema.zh.json",
40
+ "apiKey": "sk-...",
41
+ "model": "deepseek-v4-flash",
42
+ "reasoningEffort": "low",
43
+ "prices": {
44
+ "inputPerMillion": 1,
45
+ "cachedInputPerMillion": 0.02,
46
+ "outputPerMillion": 2
47
+ }
48
+ }
49
+ ```
50
+
51
+ > `$schema` 仅供编辑器自动补全/校验,运行时忽略。注释想要中文用 `.zh.json`,英文用 `.en.json`。
52
+
53
+ ### 配置字段
54
+
55
+ | 字段 | 类型 | 默认值 | 说明 |
56
+ | ---- | ---- | ------ | ---- |
57
+ | `apiKey` | string | — | DeepSeek API key(必填)。`DEEPSEEK_API_KEY` 可覆盖 |
58
+ | `baseUrl` | string | `https://api.deepseek.com` | API 基础地址(自建代理时修改) |
59
+ | `model` | string | `deepseek-v4-flash` | 模型名。`DEEPSEEK_MODEL` 可覆盖 |
60
+ | `reasoningEffort` | `off`/`low`/`high`/`auto` | `low` | `off` 关闭思考以省 token |
61
+ | `maxOutputTokens` | int ≥ 1 | `4096` | 回答最大输出 token 数 |
62
+ | `timeoutMs` | int ≥ 1 | `30000` | 单次请求超时(毫秒) |
63
+ | `cacheTtlMs` | int ≥ 1 | `300000` | 结果缓存 TTL(毫秒) |
64
+ | `maxResultChars` | int ≥ 1 | `50000` | 返回给模型的回答最大字符数 |
65
+ | `prices.inputPerMillion` | number > 0 | `1` | 输入单价(缓存未命中,元/百万 tokens) |
66
+ | `prices.cachedInputPerMillion` | number > 0 | `0.02` | 输入单价(缓存命中) |
67
+ | `prices.outputPerMillion` | number > 0 | `2` | 输出单价 |
68
+ | `prices.peak` | object | — | 峰谷定价覆盖(可选,见下) |
69
+ | `prices.models` | object | — | 按模型覆盖的价格表(key = 模型名) |
70
+
71
+ 对应环境变量:`DEEPSEEK_API_KEY`、`DEEPSEEK_BASE_URL`、`DEEPSEEK_MODEL`、`DEEPSEEK_REASONING_EFFORT`、`DEEPSEEK_MAX_OUTPUT_TOKENS`、`DEEPSEEK_TIMEOUT_MS`、`DEEPSEEK_CACHE_TTL_MS`、`DEEPSEEK_MAX_RESULT_CHARS`、`DEEPSEEK_PRICE_INPUT`、`DEEPSEEK_PRICE_CACHED_INPUT`、`DEEPSEEK_PRICE_OUTPUT`。
72
+
73
+ ### 价格与峰谷
74
+
75
+ 默认价格遵循[官方定价页](https://api-docs.deepseek.com/zh-cn/quick_start/pricing)(deepseek-v4-flash:1 / 0.02 / 2 元/百万 tokens)。价格可配置,峰谷覆盖已就绪:
76
+
77
+ ```jsonc
78
+ "prices": {
79
+ "peak": {
80
+ "multiplier": 2,
81
+ "hours": [["09:00", "12:00"], ["14:00", "18:00"]] // 半开区间 [start, end)
82
+ }
83
+ }
84
+ ```
85
+
86
+ - 高峰时段按官方定义:**北京时间每日** 9:00–12:00 与 14:00–18:00(官方"即将执行",正式通知前无需配置 `peak`)
87
+ - 高峰价格 = 平峰 × `multiplier`,适用所有计费项
88
+ - 按模型覆盖:`prices.models."deepseek-v4-pro" = { "inputPerMillion": 3, "cachedInputPerMillion": 0.025, "outputPerMillion": 6 }`——`model` 切换后自动生效
89
+ - 工具上报的 `Usage.cost` 为按配置单价估算的金额;缓存命中不产生成本(无真实调用)
90
+
91
+ ### 模型支持
92
+
93
+ Responses API 目前仅支持 `deepseek-v4-flash`;`deepseek-v4-pro` 预计 2026 年 8 月初支持。适配后设置 `"model": "deepseek-v4-pro"`(或 `DEEPSEEK_MODEL`)即可切换——价格经 `prices.models` 自动联动。
94
+
95
+ ## 使用
96
+
97
+ 向模型提出时效性或外部信息问题,它会自动调用 `deepseek_web_search`:
98
+
99
+ > 今天北京的天气怎么样?
100
+
101
+ 工具返回 DeepSeek 的综合回答(含引用)与搜索动作记录。结果按 `model:mode:query` 缓存 `cacheTtlMs`。
102
+
103
+ `/deepseek-search` 命令可查看配置状态(key 是否配置、模型、缓存条目数)并清空缓存。
104
+
105
+ ## Schema
106
+
107
+ 配置文件定义只在 `src/config-schema.ts`(TypeBox)维护**一次**,其余全部派生:
108
+
109
+ - `ConfigFileShape` 类型(`Static<>`)
110
+ - 运行时校验(`Check`/`Errors`)
111
+ - 两份生成式 JSON Schema:
112
+ - `schema/deepseek-web-search.config.schema.en.json`(英文注释)
113
+ - `schema/deepseek-web-search.config.schema.zh.json`(中文注释)
114
+
115
+ 修改定义后重新生成:
116
+
117
+ ```bash
118
+ pnpm gen:schema
119
+ ```
120
+
121
+ 生成文件随仓库提交,并有测试断言其与定义保持同步(防漂移)。
122
+
123
+ ## 开发
124
+
125
+ ```bash
126
+ pnpm check # tsc --noEmit
127
+ pnpm lint # eslint
128
+ pnpm test # vitest
129
+ pnpm gen:schema
130
+ ```
131
+
132
+ ## FAQ
133
+
134
+ - **为什么不用内置的 web search 工具?** 当你希望搜索由 DeepSeek API 支撑(例如复用已有 DeepSeek 账号/余额,或会话模型没有内置搜索)时,本工具更有用。
135
+ - **会返回来源列表吗?** DeepSeek 搜索在服务端执行,回答内含行内引用;工具同时把执行的搜索动作(`searched:`/`opened:` 行)记录在返回内容中。
136
+ - **费用怎么算?** DeepSeek 按 token 计费;工具按你配置的单价估算并上报 `Usage.cost`。参见[官方定价页](https://api-docs.deepseek.com/zh-cn/quick_start/pricing)。
137
+ - **报错 "API key is not configured"?** 设置 `DEEPSEEK_API_KEY` 或在配置文件中填 `apiKey`。
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "pi-deepseek-web-search",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "packageManager": "pnpm@11.18.0",
6
+ "description": "DeepSeek-backed web search tool for pi sessions",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/zzwtsy/pi-deepseek-web-search.git"
11
+ },
12
+ "keywords": [
13
+ "pi-package",
14
+ "pi-extension",
15
+ "web-search",
16
+ "search"
17
+ ],
18
+ "pi": {
19
+ "extensions": [
20
+ "./src/index.ts"
21
+ ]
22
+ },
23
+ "files": [
24
+ "LICENSE",
25
+ "README.md",
26
+ "README.zh.md",
27
+ "schema",
28
+ "src"
29
+ ],
30
+ "scripts": {
31
+ "clean": "rm -rf node_modules",
32
+ "check": "tsc --noEmit",
33
+ "lint": "eslint",
34
+ "lint:fix": "eslint --fix",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest",
37
+ "gen:schema": "node scripts/generate-schema.ts"
38
+ },
39
+ "peerDependencies": {
40
+ "@earendil-works/pi-ai": "*",
41
+ "@earendil-works/pi-coding-agent": "*",
42
+ "@earendil-works/pi-tui": "*",
43
+ "typebox": "*"
44
+ },
45
+ "devDependencies": {
46
+ "@antfu/eslint-config": "^9.2.0",
47
+ "@types/node": "^26.1.2",
48
+ "eslint": "^10.7.0",
49
+ "typescript": "6.0.3",
50
+ "vitest": "^4.1.10"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }
@@ -0,0 +1,186 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "apiKey": {
5
+ "type": "string",
6
+ "minLength": 1,
7
+ "description": "DeepSeek API key (required). Env DEEPSEEK_API_KEY takes precedence."
8
+ },
9
+ "baseUrl": {
10
+ "type": "string",
11
+ "default": "https://api.deepseek.com",
12
+ "description": "API base URL; change when using a proxy. Overridable via DEEPSEEK_BASE_URL."
13
+ },
14
+ "model": {
15
+ "type": "string",
16
+ "default": "deepseek-v4-flash",
17
+ "minLength": 1,
18
+ "pattern": "^(?!\\s*$)",
19
+ "description": "Model name; switch to deepseek-v4-pro once supported. Overridable via DEEPSEEK_MODEL."
20
+ },
21
+ "reasoningEffort": {
22
+ "type": "string",
23
+ "enum": [
24
+ "off",
25
+ "low",
26
+ "high",
27
+ "auto"
28
+ ],
29
+ "default": "low",
30
+ "description": "Reasoning effort: off disables thinking; auto uses model default. Overridable via DEEPSEEK_REASONING_EFFORT."
31
+ },
32
+ "maxOutputTokens": {
33
+ "type": "integer",
34
+ "minimum": 1,
35
+ "default": 4096,
36
+ "description": "Max output tokens. Overridable via DEEPSEEK_MAX_OUTPUT_TOKENS."
37
+ },
38
+ "timeoutMs": {
39
+ "type": "integer",
40
+ "minimum": 1,
41
+ "default": 30000,
42
+ "description": "Request timeout in ms. Overridable via DEEPSEEK_TIMEOUT_MS."
43
+ },
44
+ "cacheTtlMs": {
45
+ "type": "integer",
46
+ "minimum": 1,
47
+ "default": 300000,
48
+ "description": "Search result cache TTL in ms. Overridable via DEEPSEEK_CACHE_TTL_MS."
49
+ },
50
+ "maxResultChars": {
51
+ "type": "integer",
52
+ "minimum": 1,
53
+ "default": 50000,
54
+ "description": "Max result chars before truncation. Overridable via DEEPSEEK_MAX_RESULT_CHARS."
55
+ },
56
+ "prices": {
57
+ "type": "object",
58
+ "properties": {
59
+ "inputPerMillion": {
60
+ "type": "number",
61
+ "exclusiveMinimum": 0,
62
+ "default": 1,
63
+ "description": "Input price, cache miss. Overridable via DEEPSEEK_PRICE_INPUT."
64
+ },
65
+ "cachedInputPerMillion": {
66
+ "type": "number",
67
+ "exclusiveMinimum": 0,
68
+ "default": 0.02,
69
+ "description": "Input price, cache hit. Overridable via DEEPSEEK_PRICE_CACHED_INPUT."
70
+ },
71
+ "outputPerMillion": {
72
+ "type": "number",
73
+ "exclusiveMinimum": 0,
74
+ "default": 2,
75
+ "description": "Output price. Overridable via DEEPSEEK_PRICE_OUTPUT."
76
+ },
77
+ "peak": {
78
+ "type": "object",
79
+ "required": [
80
+ "multiplier",
81
+ "hours"
82
+ ],
83
+ "properties": {
84
+ "multiplier": {
85
+ "type": "number",
86
+ "exclusiveMinimum": 0,
87
+ "description": "Peak multiplier; official value is 2."
88
+ },
89
+ "hours": {
90
+ "type": "array",
91
+ "items": {
92
+ "type": "array",
93
+ "additionalItems": false,
94
+ "items": [
95
+ {
96
+ "type": "string",
97
+ "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"
98
+ },
99
+ {
100
+ "type": "string",
101
+ "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"
102
+ }
103
+ ],
104
+ "minItems": 2
105
+ },
106
+ "minItems": 1,
107
+ "description": "Peak hour ranges, half-open [start, end)."
108
+ }
109
+ },
110
+ "additionalProperties": false,
111
+ "description": "Peak pricing; official peak hours are daily 09:00-12:00 and 14:00-18:00 Beijing time."
112
+ },
113
+ "models": {
114
+ "type": "object",
115
+ "patternProperties": {
116
+ "^.*$": {
117
+ "type": "object",
118
+ "properties": {
119
+ "inputPerMillion": {
120
+ "type": "number",
121
+ "exclusiveMinimum": 0,
122
+ "description": "Input price, cache miss."
123
+ },
124
+ "cachedInputPerMillion": {
125
+ "type": "number",
126
+ "exclusiveMinimum": 0,
127
+ "description": "Input price, cache hit."
128
+ },
129
+ "outputPerMillion": {
130
+ "type": "number",
131
+ "exclusiveMinimum": 0,
132
+ "description": "Output price."
133
+ },
134
+ "peak": {
135
+ "type": "object",
136
+ "required": [
137
+ "multiplier",
138
+ "hours"
139
+ ],
140
+ "properties": {
141
+ "multiplier": {
142
+ "type": "number",
143
+ "exclusiveMinimum": 0,
144
+ "description": "Peak multiplier; official value is 2."
145
+ },
146
+ "hours": {
147
+ "type": "array",
148
+ "items": {
149
+ "type": "array",
150
+ "additionalItems": false,
151
+ "items": [
152
+ {
153
+ "type": "string",
154
+ "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"
155
+ },
156
+ {
157
+ "type": "string",
158
+ "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"
159
+ }
160
+ ],
161
+ "minItems": 2
162
+ },
163
+ "minItems": 1,
164
+ "description": "Peak hour ranges, half-open [start, end)."
165
+ }
166
+ },
167
+ "additionalProperties": false,
168
+ "description": "Peak pricing; official peak hours are daily 09:00-12:00 and 14:00-18:00 Beijing time."
169
+ }
170
+ },
171
+ "additionalProperties": false,
172
+ "description": "Per-model price override; missing fields fall back to top-level prices."
173
+ }
174
+ },
175
+ "description": "Per-model price overrides, keyed by model name."
176
+ }
177
+ },
178
+ "additionalProperties": false,
179
+ "description": "Pricing in CNY per million tokens; defaults are the official off-peak prices."
180
+ }
181
+ },
182
+ "additionalProperties": false,
183
+ "description": "Generated by pnpm gen:schema from src/config-schema.ts — do not edit. 由 src/config-schema.ts 自动生成,请勿手改。",
184
+ "$schema": "http://json-schema.org/draft-07/schema#",
185
+ "title": "deepseek-web-search config (en)"
186
+ }