dsh-connect-doubao 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -4,6 +4,37 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## 0.6.0 — 2026-11-11
8
+
9
+ > 生图这条路从「能出图」修到「在对话框里直接看到对的图」。三处都是实测出来的,不是推断。
10
+
11
+ ### 修复
12
+
13
+ - **无水印**:生图回复里同时带着 `image_ori`(右下角有「豆包AI生成」)和 `image_ori_raw`
14
+ (原图)。原来取 `image_ori`,所以每张图都带 logo。现在优先 `image_ori_raw`,取不到才回落,
15
+ 账号没开无水印档位时行为不变。
16
+ - **提示词不再被框架文本污染**:DSH 一轮请求会带 7 条 message——开发者提示、运行时快照、
17
+ 技能目录、MCP 列表、记忆页面——真正的用户描述夹在其中。原来取「最后一条 user 消息」,
18
+ 拿到的是 `<system-reminder>` 块,于是豆包把 `turn 1 step 1`、工具名当成画面内容画了出来
19
+ (用户看到的 “1turn / tup / tun” 残影)。现在按三条标准筛:长度 ≤600 字符、不以 `<` 开头、
20
+ 不含已知框架标记。
21
+ - **自动补「生成图片:」前缀**:桌面客户端靠 `chat_ability.ability_param.reply_message_format`
22
+ 改写正文,外部客户端没有这个钩子,服务端会把请求当普通对话回答。`withImagePrefix()` 补上
23
+ 同样的改写;已有前缀不重复加,普通对话完全不受影响。
24
+ - **模型 id 宽松匹配**:DSH 可能带 provider 前缀(`doubao/image-gen`)或大小写不同,
25
+ 漏判会静默回落到完整 agent 提示词——这正是提示词被污染的另一半原因。
26
+
27
+ ### 其它
28
+
29
+ - 生图版本名改为读插件根目录的 `image-models.json`(缺省 Seedream 5.5)。该文件由
30
+ `doubao_imagemodels.py --sync` 从服务端 `get_item_conf` 生成,服务端上新版本后改数据即可,
31
+ 不用改代码。
32
+ - 新增 `DSH_DOUBAO_DEBUG_PROMPT=1`:把实际发出的 prompt 与原始 messages 结构打到 stderr,
33
+ 并追加到 `~/.dsh/doubao-prompt.log`。默认关闭。
34
+ - 新增测试:无水印变体选择、前缀注入(含幂等与普通对话不受影响)。
35
+
36
+ ---
37
+
7
38
  ## 0.5.0 — 2026-11-07
8
39
 
9
40
  > 取凭据的路只剩一条:**浏览器扫码登录**。上一轮加的 `authMode` 开关(客户端 / 浏览器)
package/README.md CHANGED
@@ -39,7 +39,7 @@
39
39
  - **两组豆包模型** —— 对话模式两条(快速 / 2.1 Turbo·专家)与「工作任务」模式三条
40
40
  (2.1 Lite `seed-lite-7b`、2.1 Pro `5`、自动 `9`)。任务模型走的是**会员付费额度**,
41
41
  选中即自动切到任务模式的完整请求形态。
42
- - **生图(Seedream 5.0)** —— 模型选择器里选「豆包 生图」,回复即以 Markdown 图片返回真实生成图,可直接下载落盘。2026-11-02 实测端到端通过。
42
+ - **生图(Seedream 5.5)** —— 模型选择器里选「豆包 生图」,回复即以 Markdown 图片返回真实生成图,可直接下载落盘。2026-11-02 实测端到端通过。
43
43
  - **推理强度三档** —— 低 / 中 / 高,对应上游 `reasoning_effort` 实测值 **3 / 4 / 5**。
44
44
  - **深度思考默认开启** —— 不再需要额外开关:非「工作任务」模型每轮发 `need_deep_think: 3`,任务模型沿用抓包到的真实形态 `10001`。`DSH_DOUBAO_DEEP_THINK=0` 可关掉。
45
45
  - **只读额度面板** —— 5 小时限额、周额度、活动赠送额度三条进度条,各带**重置倒计时**;设置面板里手动刷新 + 5 分钟自动刷新。
@@ -164,16 +164,23 @@ POST /alice/office/tool_local/msg/complete # 标记该指令完成
164
164
  技能全表(客户端枚举原样抄录,非推测):`0` 自由对话、`2` 写作、`3` 生图、`4` 搜索、`5` 翻译、
165
165
  `6` 阅读、`7` 网页、`8` 深度搜索、`9` 音乐、`11` 教育、`13` 代码执行、`16` 代码助手、`17` 视频、`18` PPT。
166
166
 
167
- 本插件目前只接了 **生图**:模型选择器里的「豆包 生图(Seedream 5.0)」是 DSH 侧的能力别名
167
+ 本插件目前只接了 **生图**:模型选择器里的「豆包 生图(Seedream 5.5)」是 DSH 侧的能力别名
168
168
  (`image-gen`,**不是** `model_item_key`),选中后 shim 发一条普通对话轮并带上 `input_skill: imageGen`,
169
169
  再把返回的图片以 `![…](url)` 追加到正文。
170
170
 
171
- **两个实测细节**:
172
-
171
+ **四个实测细节**:
172
+
173
+ - **取无水印原图**:同一次生成,流里同时带 `image_ori`(右下角有「豆包AI生成」)和
174
+ `image_ori_raw`(原图)。插件优先取 `image_ori_raw`,取不到才回落 `image_ori`,
175
+ 所以账号没开无水印档位时行为不变、不会报错。
176
+ - **自动补「生成图片:」前缀**:桌面客户端靠 `chat_ability.ability_param.reply_message_format`
177
+ 改写正文,外部客户端没有这个钩子,服务端会把请求当普通对话回答。`withImagePrefix()`
178
+ 补上同样的改写:已有前缀不重复加,普通对话完全不受影响。
179
+ - **只把用户那句话发出去**:一轮请求里除了用户描述,还夹着开发者提示、运行时快照、
180
+ 技能目录、MCP 列表等机器块。插件按「长度 ≤600 字符、不以 `<` 开头、不含已知框架标记」
181
+ 筛出真正的描述,否则豆包会把 `turn 1 step 1` 这类框架文本当成画面内容画进去。
173
182
  - 图片 URL 的签名有效期极长(抓到的 `x-expires` 在 2037 年),但服务端会把 `.jpeg` 结尾的 URL
174
183
  实际返回 **PNG 字节** —— 落盘时按内容判断格式,别信扩展名。
175
- - 提示词会被服务端改写扩写(`creation_material_info.creation_prompt` 里是扩写后的版本),
176
- 所以产物质量与措辞由豆包决定,不是逐字照发。
177
184
 
178
185
  验证脚本:`node scripts/verify-imagegen.mjs`(会真实消耗生图额度)。
179
186
 
@@ -1,4 +1,4 @@
1
- import { O as classifyDoubaoFailure, f as DoubaoUpstreamError } from "./doubao-upstream-CJpMsaTX.js";
1
+ import { O as classifyDoubaoFailure, f as DoubaoUpstreamError } from "./doubao-upstream-CAg0AS4T.js";
2
2
  //#region src/cli-doctor.d.ts
3
3
  type CheckStatus = 'ok' | 'fail' | 'skip';
4
4
  interface DoctorCheck {
package/lib/cli-doctor.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { Ct as discoverDoubaoModels, D as classifyDoubaoFailure, G as loadDoubaoCredentials, J as describeProfileLocation, P as probeAccount, Z as listDoubaoProfiles, dt as DOUBAO_MODELS, ft as DOUBAO_PROVIDER, i as formatDuration, m as DoubaoUpstreamError, n as fetchQuota, o as millisUntilReset, pt as DOUBAO_PROVIDER_DISPLAY_NAME, r as findWindow, z as REQUIRED_COOKIE_NAMES } from "./doubao-quota-Bq-V97h9.js";
3
- import { _ as createDoubaoAdapter, a as doubaoQuotaView, d as discoverAllCachedModels, h as createDoubaoShim, m as liveModels, r as DOUBAO_QUOTA_PATH } from "./doubao-status-uEa8afa1.js";
2
+ import { B as REQUIRED_COOKIE_NAMES, D as classifyDoubaoFailure, K as loadDoubaoCredentials, P as probeAccount, Q as listDoubaoProfiles, Y as describeProfileLocation, ft as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, mt as DOUBAO_PROVIDER_DISPLAY_NAME, n as fetchQuota, o as millisUntilReset, pt as DOUBAO_PROVIDER, r as findWindow, wt as discoverDoubaoModels } from "./doubao-quota-CAdK_fAm.js";
3
+ import { _ as createDoubaoAdapter, a as doubaoQuotaView, d as discoverAllCachedModels, h as createDoubaoShim, m as liveModels, r as DOUBAO_QUOTA_PATH } from "./doubao-status-gcSuFOQg.js";
4
4
  //#region src/cli-doctor.ts
5
5
  /**
6
6
  * `doctor` — verify the whole stack end to end without spending inference quota.
package/lib/cli-probe.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Dt as findReasoningLevel, Et as findDoubaoModel, F as streamChat, G as loadDoubaoCredentials, P as probeAccount, dt as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, n as fetchQuota, o as millisUntilReset, r as findWindow } from "./doubao-quota-Bq-V97h9.js";
2
+ import { Dt as findDoubaoModel, F as streamChat, K as loadDoubaoCredentials, Ot as findReasoningLevel, P as probeAccount, ft as DOUBAO_MODELS, i as formatDuration, m as DoubaoUpstreamError, n as fetchQuota, o as millisUntilReset, r as findWindow } from "./doubao-quota-CAdK_fAm.js";
3
3
  //#region src/cli-probe.ts
4
4
  /**
5
5
  * Doubao smoke probe.
@@ -1,7 +1,7 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
3
2
  import { homedir, hostname, tmpdir } from "node:os";
4
3
  import { dirname, join } from "node:path";
4
+ import { randomUUID } from "node:crypto";
5
5
  import { spawnSync } from "node:child_process";
6
6
  //#region src/doubao-catalog.ts
7
7
  /**
@@ -188,7 +188,20 @@ const CREATION_BLOCK_TYPE = 2074;
188
188
  * DSH's model picker without inventing a second UI.
189
189
  */
190
190
  const DOUBAO_IMAGE_MODEL_ID = "image-gen";
191
- const DOUBAO_IMAGE_MODEL_NAME = "豆包 生图(Seedream 5.0)";
191
+ /**
192
+ * IMAGEGEN_LABEL_OVERLAY: 生图版本名以插件根目录的 image-models.json 为准,
193
+ * 该文件由 doubao_imagemodels.py --sync 从服务端 get_item_conf 生成。
194
+ */
195
+ function imageModelLabelFromOverlay() {
196
+ try {
197
+ const url = new URL("../image-models.json", import.meta.url);
198
+ const parsed = JSON.parse(readFileSync(url, "utf8"));
199
+ return typeof parsed.label === "string" && parsed.label !== "" ? parsed.label : void 0;
200
+ } catch {
201
+ return;
202
+ }
203
+ }
204
+ const DOUBAO_IMAGE_MODEL_NAME = imageModelLabelFromOverlay() ?? "豆包 生图(Seedream 5.5)";
192
205
  /** The chat model a skill turn rides on: the app's own default. */
193
206
  const SKILL_CARRIER_MODEL_ID = "0";
194
207
  /**
@@ -1091,7 +1104,25 @@ function buildGeneralTaskParam(localMessageId, workspace, prompt) {
1091
1104
  * local sandbox and workspace paths, none of which apply to an external client,
1092
1105
  * and the endpoint has been observed answering correctly without it.
1093
1106
  */
1107
+ /**
1108
+ * Add the 「生成图片:」 prefix that Doubao's image skill requires.
1109
+ *
1110
+ * The desktop app gets this for free: its `chat_ability.ability_param` carries
1111
+ * `reply_message_format: "生成图片:%s"`, which rewrites the outgoing text before
1112
+ * the request leaves. An external client has no such hook, so the same rewrite
1113
+ * happens here. Without it the server treats the turn as ordinary chat and
1114
+ * answers with prose instead of drawing.
1115
+ *
1116
+ * Deliberately ONLY the prefix: appending extra instructions makes Doubao read
1117
+ * them as part of the subject and drop the picture entirely (measured).
1118
+ */
1119
+ function withImagePrefix(prompt, options = {}) {
1120
+ if (!(options.skill === "imageGen" || options.modelKey === "image-gen")) return prompt;
1121
+ if (/^\s*(生成图片|生成一张|画一张|画个|绘制)/.test(prompt)) return prompt;
1122
+ return `生成图片:${prompt}`;
1123
+ }
1094
1124
  function buildChatBody(prompt, options = {}) {
1125
+ prompt = withImagePrefix(prompt, options);
1095
1126
  const model = findDoubaoModel(options.modelKey);
1096
1127
  const level = findReasoningLevel(options.reasoningLevel);
1097
1128
  const task = taskModeEnabled(options);
@@ -1353,7 +1384,7 @@ function toDoubaoImage(raw) {
1353
1384
  const value = image[key];
1354
1385
  return typeof value === "object" && value !== null ? value : void 0;
1355
1386
  };
1356
- const best = pick("image_ori") ?? pick("image_preview") ?? pick("image_thumb");
1387
+ const best = pick("image_ori_raw") ?? pick("image_ori") ?? pick("image_preview") ?? pick("image_thumb");
1357
1388
  if (best === void 0 || typeof best.url !== "string" || best.url === "") return void 0;
1358
1389
  const taskId = typeof creation.id === "string" ? creation.id : typeof creation.id === "number" ? String(creation.id) : void 0;
1359
1390
  const out = { url: best.url };
@@ -2139,4 +2170,4 @@ function formatDuration(ms) {
2139
2170
  return parts.join(" ") || "0s";
2140
2171
  }
2141
2172
  //#endregion
2142
- export { resolveUserProvided as $, extractModel as A, needDeepThinkValue as At, clearBrowserCredentials as B, buildGeneralTaskParam as C, discoverDoubaoModels as Ct, classifyDoubaoFailure as D, findReasoningLevel as Dt, chat as E, findDoubaoModel as Et, streamChat as F, loadDoubaoCredentials as G, hasBrowserCredentials as H, taskModeEnabled as I, describeProfileLocation as J, saveBrowserCredentials as K, taskWorkspaceOf as L, isRetryableFailure as M, parseFrames as N, collectBlocks as O, inputSkillOf as Ot, probeAccount as P, looksLikeProfile as Q, CREDENTIAL_TTL_MS as R, buildChatBody as S, TASK_SANDBOX_AUTH_ALLOW_ALL as St, buildQueryUrl as T, enabledModelsOf as Tt, invalidateCredentialCache as U, clearCredentialCache as V, loadBrowserCredentials as W, findDoubaoUserDataDir as X, extractUserDataDir as Y, listDoubaoProfiles as Z, TOOL_LOCAL_ACK_ENDPOINT as _, NO_THINKING_MODEL_IDS as _t, invalidateQuotaCache as a, DEFAULT_REASONING_LEVEL_ID as at, applyRenewals as b, TASK_RUNTIME_CLOUD_VM as bt, ACCOUNT_ENDPOINT as c, DOUBAO_IMAGE_MODEL_ID as ct, DEFAULT_BOT_ID as d, DOUBAO_MODELS as dt, setProfileOverride as et, DOUBAO_ERROR_HINTS as f, DOUBAO_PROVIDER as ft, RUNTIME_VERSION as g, DOUBAO_UNAVAILABLE_MODELS as gt, QUOTA_ENDPOINT as h, DOUBAO_SKILLS as ht, formatDuration as i, DEEP_THINK_ON as it, invalidateRenewals as j, supportsReasoning as jt, describeDoubaoFailure as k, isTaskModel as kt, CHAT_ENDPOINT as l, DOUBAO_IMAGE_MODEL_NAME as lt, DoubaoUpstreamError as m, DOUBAO_REASONING_LEVELS as mt, fetchQuota as n, CREATION_BLOCK_TYPE as nt, millisUntilReset as o, DOUBAO_CONTEXT_WINDOW as ot, DOUBAO_VERSION as p, DOUBAO_PROVIDER_DISPLAY_NAME as pt, PROFILE_ENV as q, findWindow as r, DEEP_THINK_OFF as rt, normalizeWindow as s, DOUBAO_DEFAULT_MODEL_ID as st, QUOTA_TTL_MS as t, CHAT_AGENT_MODE as tt, CLIENT_PARAMS as u, DOUBAO_MAX_TOKENS as ut, TOOL_LOCAL_COMPLETE_ENDPOINT as v, SKILL_CARRIER_MODEL_ID as vt, buildHeaders as w, doubaoCatalogEntries as wt, assembleReplyText as x, TASK_RUNTIME_LOCAL_PC as xt, TOOL_LOCAL_UPLOAD_ENDPOINT as y, TASK_AGENT_MODE as yt, REQUIRED_COOKIE_NAMES as z };
2173
+ export { looksLikeProfile as $, extractModel as A, isTaskModel as At, REQUIRED_COOKIE_NAMES as B, buildGeneralTaskParam as C, TASK_SANDBOX_AUTH_ALLOW_ALL as Ct, classifyDoubaoFailure as D, findDoubaoModel as Dt, chat as E, enabledModelsOf as Et, streamChat as F, loadBrowserCredentials as G, clearCredentialCache as H, taskModeEnabled as I, PROFILE_ENV as J, loadDoubaoCredentials as K, taskWorkspaceOf as L, isRetryableFailure as M, supportsReasoning as Mt, parseFrames as N, collectBlocks as O, findReasoningLevel as Ot, probeAccount as P, listDoubaoProfiles as Q, withImagePrefix as R, buildChatBody as S, TASK_RUNTIME_LOCAL_PC as St, buildQueryUrl as T, doubaoCatalogEntries as Tt, hasBrowserCredentials as U, clearBrowserCredentials as V, invalidateCredentialCache as W, extractUserDataDir as X, describeProfileLocation as Y, findDoubaoUserDataDir as Z, TOOL_LOCAL_ACK_ENDPOINT as _, DOUBAO_UNAVAILABLE_MODELS as _t, invalidateQuotaCache as a, DEEP_THINK_ON as at, applyRenewals as b, TASK_AGENT_MODE as bt, ACCOUNT_ENDPOINT as c, DOUBAO_DEFAULT_MODEL_ID as ct, DEFAULT_BOT_ID as d, DOUBAO_MAX_TOKENS as dt, resolveUserProvided as et, DOUBAO_ERROR_HINTS as f, DOUBAO_MODELS as ft, RUNTIME_VERSION as g, DOUBAO_SKILLS as gt, QUOTA_ENDPOINT as h, DOUBAO_REASONING_LEVELS as ht, formatDuration as i, DEEP_THINK_OFF as it, invalidateRenewals as j, needDeepThinkValue as jt, describeDoubaoFailure as k, inputSkillOf as kt, CHAT_ENDPOINT as l, DOUBAO_IMAGE_MODEL_ID as lt, DoubaoUpstreamError as m, DOUBAO_PROVIDER_DISPLAY_NAME as mt, fetchQuota as n, CHAT_AGENT_MODE as nt, millisUntilReset as o, DEFAULT_REASONING_LEVEL_ID as ot, DOUBAO_VERSION as p, DOUBAO_PROVIDER as pt, saveBrowserCredentials as q, findWindow as r, CREATION_BLOCK_TYPE as rt, normalizeWindow as s, DOUBAO_CONTEXT_WINDOW as st, QUOTA_TTL_MS as t, setProfileOverride as tt, CLIENT_PARAMS as u, DOUBAO_IMAGE_MODEL_NAME as ut, TOOL_LOCAL_COMPLETE_ENDPOINT as v, NO_THINKING_MODEL_IDS as vt, buildHeaders as w, discoverDoubaoModels as wt, assembleReplyText as x, TASK_RUNTIME_CLOUD_VM as xt, TOOL_LOCAL_UPLOAD_ENDPOINT as y, SKILL_CARRIER_MODEL_ID as yt, CREDENTIAL_TTL_MS as z };
@@ -1,13 +1,13 @@
1
- import { D as classifyDoubaoFailure, E as chat, Et as findDoubaoModel, G as loadDoubaoCredentials, J as describeProfileLocation, K as saveBrowserCredentials, M as isRetryableFailure, Tt as enabledModelsOf, U as invalidateCredentialCache, V as clearCredentialCache, X as findDoubaoUserDataDir, a as invalidateQuotaCache, ct as DOUBAO_IMAGE_MODEL_ID, dt as DOUBAO_MODELS, ft as DOUBAO_PROVIDER, gt as DOUBAO_UNAVAILABLE_MODELS, jt as supportsReasoning, kt as isTaskModel, lt as DOUBAO_IMAGE_MODEL_NAME, m as DoubaoUpstreamError, n as fetchQuota, o as millisUntilReset, ot as DOUBAO_CONTEXT_WINDOW, pt as DOUBAO_PROVIDER_DISPLAY_NAME, r as findWindow, ut as DOUBAO_MAX_TOKENS, wt as doubaoCatalogEntries } from "./doubao-quota-Bq-V97h9.js";
1
+ import { At as isTaskModel, D as classifyDoubaoFailure, Dt as findDoubaoModel, E as chat, Et as enabledModelsOf, H as clearCredentialCache, K as loadDoubaoCredentials, M as isRetryableFailure, Mt as supportsReasoning, Tt as doubaoCatalogEntries, W as invalidateCredentialCache, Y as describeProfileLocation, Z as findDoubaoUserDataDir, _t as DOUBAO_UNAVAILABLE_MODELS, a as invalidateQuotaCache, dt as DOUBAO_MAX_TOKENS, ft as DOUBAO_MODELS, lt as DOUBAO_IMAGE_MODEL_ID, m as DoubaoUpstreamError, mt as DOUBAO_PROVIDER_DISPLAY_NAME, n as fetchQuota, o as millisUntilReset, pt as DOUBAO_PROVIDER, q as saveBrowserCredentials, r as findWindow, st as DOUBAO_CONTEXT_WINDOW, ut as DOUBAO_IMAGE_MODEL_NAME } from "./doubao-quota-CAdK_fAm.js";
2
2
  import { createProvider } from "@earendil-works/pi-ai";
3
3
  import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy";
4
4
  import { resolveRetryPolicy } from "@deepseek-ai/dsh-llm";
5
5
  import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
6
- import { createServer } from "node:http";
7
- import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
8
- import { existsSync, mkdirSync, readFileSync, readdirSync } from "node:fs";
6
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
9
7
  import { homedir } from "node:os";
10
8
  import { join } from "node:path";
9
+ import { createServer } from "node:http";
10
+ import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
11
11
  import { spawn, spawnSync } from "node:child_process";
12
12
  //#region src/doubao-adapter.ts
13
13
  /**
@@ -619,15 +619,53 @@ function requestOptions(parsed) {
619
619
  };
620
620
  }
621
621
  /**
622
- * Render generated images as Markdown so they survive a text-only transport.
622
+ * IMAGEGEN_LOCAL_FILE: download the picture and reference it locally.
623
623
  *
624
- * The OpenAI surface pi-ai speaks has no image part on the assistant side, so
625
- * the URL in text is what reaches the user — and it is also what makes the
626
- * Harness able to download the file afterwards.
624
+ * The Harness renders local files reliably; a signed CDN URL in Markdown shows
625
+ * up as 「图片无法预览」 (the `~tplv-…` segment breaks link parsing and the
626
+ * origin may be blocked). Saving the bytes next to the session sidesteps both.
627
+ *
628
+ * Returns Markdown with the local path, or the remote URL when the download
629
+ * fails — a broken preview is better than a missing picture.
627
630
  */
628
- function imageMarkdown(images) {
631
+ async function imageMarkdownLocal(images) {
629
632
  if (images.length === 0) return "";
630
- return images.map((image, i) => `![豆包生图 ${i + 1}](${image.url})`).join("\n\n");
633
+ const dir = join(homedir(), ".dsh", "doubao-images");
634
+ const parts = [];
635
+ for (const [i, image] of images.entries()) {
636
+ const fallback = `![豆包生图 ${i + 1}](${markdownSafeUrl(image.url)})`;
637
+ try {
638
+ const res = await fetch(image.url);
639
+ if (!res.ok) {
640
+ parts.push(fallback);
641
+ continue;
642
+ }
643
+ const buf = Buffer.from(await res.arrayBuffer());
644
+ mkdirSync(dir, { recursive: true });
645
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
646
+ const file = join(dir, `doubao-${stamp}-${i + 1}.png`);
647
+ writeFileSync(file, buf);
648
+ parts.push(`![豆包生图 ${i + 1}](${file.replace(/\\/g, "/")})`);
649
+ } catch {
650
+ parts.push(fallback);
651
+ }
652
+ }
653
+ return parts.join("\n\n");
654
+ }
655
+ /**
656
+ * IMAGEGEN_URL_SAFE: make a CDN URL survive Markdown link parsing.
657
+ *
658
+ * Doubao's signed URLs carry `~tplv-…` and `x-signature=…%3D`. A bare `~` is the
659
+ * strikethrough marker, so the link breaks and the Harness renders
660
+ * 「图片无法预览:*」 instead of the picture. Percent-encoding the path segment
661
+ * keeps the bytes identical while removing the ambiguous characters.
662
+ */
663
+ function markdownSafeUrl(raw) {
664
+ if (typeof raw !== "string" || raw === "") return "";
665
+ const q = raw.indexOf("?");
666
+ const path = q === -1 ? raw : raw.slice(0, q);
667
+ const query = q === -1 ? "" : raw.slice(q);
668
+ return path.replace(/~/g, "%7E").replace(/\(/g, "%28").replace(/\)/g, "%29") + query.replace(/\(/g, "%28").replace(/\)/g, "%29");
631
669
  }
632
670
  /**
633
671
  * Flatten pi-ai's content shapes (string | block array) into plain text.
@@ -664,6 +702,64 @@ function flattenContent(content) {
664
702
  * shape the tool contract promises — the model is asked to recognise that prefix,
665
703
  * so the two sides must not drift apart.
666
704
  */
705
+ /**
706
+ * Whether this turn targets the image alias.
707
+ *
708
+ * DSH may spell the model id with a provider prefix (`doubao/image-gen`) or in
709
+ * another case; a missed match silently falls back to the full agent prompt,
710
+ * which is how framework text ended up drawn into the picture.
711
+ */
712
+ function isImageModel(model) {
713
+ if (typeof model !== "string" || model === "") return false;
714
+ return (model.includes("/") ? model.slice(model.lastIndexOf("/") + 1) : model).trim().toLowerCase() === DOUBAO_IMAGE_MODEL_ID;
715
+ }
716
+ /**
717
+ * IMAGEGEN_PROMPT: pick the sentence the user actually typed.
718
+ *
719
+ * The transcript DSH hands us is not just that sentence: it carries the
720
+ * developer prompt, a runtime snapshot, the skill catalog, the MCP listing and
721
+ * memory pages, each as its own `user` message. Taking the last user message
722
+ * therefore picked up a `<system-reminder>` block, and Doubao drew that text
723
+ * into the picture — the reported "turn 1 step 1 / tup / tun" artefacts.
724
+ *
725
+ * A picture description is short and plain, so a message qualifies only when it
726
+ * is bounded in length and carries no known marker or XML-ish wrapper.
727
+ */
728
+ const FRAMEWORK_MARKERS = [
729
+ "Current runtime context",
730
+ "Time sampled while preparing",
731
+ "Elapsed since the preceding",
732
+ "<system-reminder>",
733
+ "<available_skills>",
734
+ "<mcp_catalog>",
735
+ "<hindsight_pages>",
736
+ "<hindsight_knowledge",
737
+ "A skill is a reusable set of task-specific instructions",
738
+ "The following MCP servers are available",
739
+ "You are an AI agent powered by"
740
+ ];
741
+ /** Anything longer than this is machine context, not a picture request. */
742
+ const MAX_IMAGE_PROMPT_CHARS = 600;
743
+ function looksLikeFramework(text) {
744
+ const head = text.slice(0, 400);
745
+ if (head.startsWith("<")) return true;
746
+ if (/^[<\[]/.test(head) && head.includes(">")) return true;
747
+ return FRAMEWORK_MARKERS.some((marker) => head.includes(marker));
748
+ }
749
+ function buildImagePrompt(all, outgoing) {
750
+ const source = all.length > 0 ? all : outgoing;
751
+ let fallback = "";
752
+ for (let i = source.length - 1; i >= 0; i -= 1) {
753
+ const message = source[i];
754
+ if (message === void 0) continue;
755
+ if ((message.role ?? "user") !== "user") continue;
756
+ const text = flattenContent(message.content).trim();
757
+ if (text === "" || looksLikeFramework(text)) continue;
758
+ if (text.length <= MAX_IMAGE_PROMPT_CHARS) return text;
759
+ if (fallback === "") fallback = text.slice(0, MAX_IMAGE_PROMPT_CHARS);
760
+ }
761
+ return fallback;
762
+ }
667
763
  function buildPrompt(messages) {
668
764
  if (!Array.isArray(messages) || messages.length === 0) return "";
669
765
  const turns = [];
@@ -923,7 +1019,7 @@ function createDoubaoShim(options = {}) {
923
1019
  });
924
1020
  if (calls.length > 0) finishReason = "tool_calls";
925
1021
  }
926
- const markdown = imageMarkdown(result.images);
1022
+ const markdown = await imageMarkdownLocal(result.images);
927
1023
  if (markdown !== "") send({ choices: [{
928
1024
  index: 0,
929
1025
  delta: { content: `\n\n${markdown}` },
@@ -1044,7 +1140,7 @@ function createDoubaoShim(options = {}) {
1044
1140
  const useDelta = delta.length > 0;
1045
1141
  const isContinuationTurn = continuing && useDelta;
1046
1142
  const outgoing = useDelta ? delta : parsed.messages ?? [];
1047
- const promptBody = buildPrompt(outgoing);
1143
+ const promptBody = isImageModel(parsed.model) ? buildImagePrompt(parsed.messages ?? [], outgoing) : buildPrompt(outgoing);
1048
1144
  if (!promptBody) {
1049
1145
  writeOpenAIError(res, 400, "invalid_request", "no usable message content");
1050
1146
  return;
@@ -1056,7 +1152,17 @@ function createDoubaoShim(options = {}) {
1056
1152
  */
1057
1153
  const emulate = emulationOn() && (parsed.tools?.length ?? 0) > 0;
1058
1154
  const prompt = emulate ? `${promptBody}${buildToolContract(parsed.tools ?? [])}` : promptBody;
1059
- if (process.env.DSH_DOUBAO_DEBUG_PROMPT === "1") process.stderr.write(`[prompt] chars=${prompt.length} tools=${parsed.tools?.length ?? 0} emulate=${emulate}\n${prompt.slice(0, 1200)}\n---\n`);
1155
+ if (process.env.DSH_DOUBAO_DEBUG_PROMPT === "1") {
1156
+ const raw = JSON.stringify((parsed.messages ?? []).map((m) => ({
1157
+ r: m.role,
1158
+ t: flattenContent(m.content).slice(0, 200)
1159
+ })));
1160
+ const line = `[prompt] model=${String(parsed.model)} chars=${prompt.length} tools=${parsed.tools?.length ?? 0} emulate=${emulate} msgs=${(parsed.messages ?? []).length}\nRAW=${raw}\n${prompt.slice(0, 2e3)}\n---\n`;
1161
+ process.stderr.write(line);
1162
+ try {
1163
+ appendFileSync(join(homedir(), ".dsh", "doubao-prompt.log"), line);
1164
+ } catch {}
1165
+ }
1060
1166
  const { signal, onActivity, clientGone } = createRequestLifecycle(res);
1061
1167
  const upstreamOptions = {
1062
1168
  ...requestOptions(parsed),
@@ -1078,7 +1184,7 @@ function createDoubaoShim(options = {}) {
1078
1184
  calls: [],
1079
1185
  text: result.text
1080
1186
  };
1081
- const content = [emulated.text, result.images.length > 0 ? imageMarkdown(result.images) : ""].filter((part) => part !== "").join("\n\n");
1187
+ const content = [emulated.text, result.images.length > 0 ? await imageMarkdownLocal(result.images) : ""].filter((part) => part !== "").join("\n\n");
1082
1188
  const sent = findDoubaoModel(parsed.model);
1083
1189
  writeJson(res, 200, {
1084
1190
  id: `doubao-${Date.now()}`,
@@ -236,7 +236,7 @@ declare const CREATION_BLOCK_TYPE = 2074;
236
236
  * DSH's model picker without inventing a second UI.
237
237
  */
238
238
  declare const DOUBAO_IMAGE_MODEL_ID = "image-gen";
239
- declare const DOUBAO_IMAGE_MODEL_NAME = "豆包 生图(Seedream 5.0)";
239
+ declare const DOUBAO_IMAGE_MODEL_NAME: string;
240
240
  /** The chat model a skill turn rides on: the app's own default. */
241
241
  declare const SKILL_CARRIER_MODEL_ID = "0";
242
242
  interface DoubaoModelInfo {
@@ -629,6 +629,19 @@ declare function buildGeneralTaskParam(localMessageId: string, workspace: string
629
629
  * local sandbox and workspace paths, none of which apply to an external client,
630
630
  * and the endpoint has been observed answering correctly without it.
631
631
  */
632
+ /**
633
+ * Add the 「生成图片:」 prefix that Doubao's image skill requires.
634
+ *
635
+ * The desktop app gets this for free: its `chat_ability.ability_param` carries
636
+ * `reply_message_format: "生成图片:%s"`, which rewrites the outgoing text before
637
+ * the request leaves. An external client has no such hook, so the same rewrite
638
+ * happens here. Without it the server treats the turn as ordinary chat and
639
+ * answers with prose instead of drawing.
640
+ *
641
+ * Deliberately ONLY the prefix: appending extra instructions makes Doubao read
642
+ * them as part of the subject and drop the picture entirely (measured).
643
+ */
644
+ declare function withImagePrefix(prompt: string, options?: ChatRequestOptions): string;
632
645
  declare function buildChatBody(prompt: string, options?: ChatRequestOptions): {
633
646
  messages: {
634
647
  local_message_id: `${string}-${string}-${string}-${string}-${string}`;
@@ -916,4 +929,4 @@ declare function probeAccount(credentials: DoubaoCredentials): Promise<{
916
929
  detail: string;
917
930
  }>;
918
931
  //#endregion
919
- export { DOUBAO_SKILLS as $, describeDoubaoFailure as A, saveBrowserCredentials as At, CREATION_BLOCK_TYPE as B, buildChatBody as C, REQUIRED_COOKIE_NAMES as Ct, chat as D, invalidateCredentialCache as Dt, buildQueryUrl as E, hasBrowserCredentials as Et, probeAccount as F, DOUBAO_DEFAULT_MODEL_ID as G, DEEP_THINK_ON as H, streamChat as I, DOUBAO_MAX_TOKENS as J, DOUBAO_IMAGE_MODEL_ID as K, taskModeEnabled as L, invalidateRenewals as M, isRetryableFailure as N, classifyDoubaoFailure as O, loadBrowserCredentials as Ot, parseFrames as P, DOUBAO_REASONING_LEVELS as Q, taskWorkspaceOf as R, assembleReplyText as S, DoubaoCredentials as St, buildHeaders as T, clearCredentialCache as Tt, DEFAULT_REASONING_LEVEL_ID as U, DEEP_THINK_OFF as V, DOUBAO_CONTEXT_WINDOW as W, DOUBAO_PROVIDER as X, DOUBAO_MODELS as Y, DOUBAO_PROVIDER_DISPLAY_NAME as Z, StreamCallbacks as _, inputSkillOf as _t, DEFAULT_BOT_ID as a, DoubaoSkillName as at, TOOL_LOCAL_UPLOAD_ENDPOINT as b, supportsReasoning as bt, DoubaoChatResult as c, TASK_AGENT_MODE as ct, DoubaoMessage as d, TASK_SANDBOX_AUTH_ALLOW_ALL as dt, DOUBAO_UNAVAILABLE_MODELS as et, DoubaoUpstreamError as f, discoverDoubaoModels as ft, RUNTIME_VERSION as g, findReasoningLevel as gt, QUOTA_ENDPOINT as h, findDoubaoModel as ht, ChatRequestOptions as i, DoubaoReasoningLevel as it, extractModel as j, collectBlocks as k, loadDoubaoCredentials as kt, DoubaoErrorKind as l, TASK_RUNTIME_CLOUD_VM as lt, DoubaoUsage as m, enabledModelsOf as mt, CHAT_ENDPOINT as n, DoubaoCatalogEntry as nt, DOUBAO_ERROR_HINTS as o, NO_THINKING_MODEL_IDS as ot, DoubaoUpstreamErrorMeta as p, doubaoCatalogEntries as pt, DOUBAO_IMAGE_MODEL_NAME as q, CLIENT_PARAMS as r, DoubaoModelInfo as rt, DOUBAO_VERSION as s, SKILL_CARRIER_MODEL_ID as st, ACCOUNT_ENDPOINT as t, DiscoveredDoubaoModel as tt, DoubaoImage as u, TASK_RUNTIME_LOCAL_PC as ut, TOOL_LOCAL_ACK_ENDPOINT as v, isTaskModel as vt, buildGeneralTaskParam as w, clearBrowserCredentials as wt, applyRenewals as x, CREDENTIAL_TTL_MS as xt, TOOL_LOCAL_COMPLETE_ENDPOINT as y, needDeepThinkValue as yt, CHAT_AGENT_MODE as z };
932
+ export { DOUBAO_REASONING_LEVELS as $, describeDoubaoFailure as A, loadDoubaoCredentials as At, CHAT_AGENT_MODE as B, buildChatBody as C, DoubaoCredentials as Ct, chat as D, hasBrowserCredentials as Dt, buildQueryUrl as E, clearCredentialCache as Et, probeAccount as F, DOUBAO_CONTEXT_WINDOW as G, DEEP_THINK_OFF as H, streamChat as I, DOUBAO_IMAGE_MODEL_NAME as J, DOUBAO_DEFAULT_MODEL_ID as K, taskModeEnabled as L, invalidateRenewals as M, isRetryableFailure as N, classifyDoubaoFailure as O, invalidateCredentialCache as Ot, parseFrames as P, DOUBAO_PROVIDER_DISPLAY_NAME as Q, taskWorkspaceOf as R, assembleReplyText as S, CREDENTIAL_TTL_MS as St, buildHeaders as T, clearBrowserCredentials as Tt, DEEP_THINK_ON as U, CREATION_BLOCK_TYPE as V, DEFAULT_REASONING_LEVEL_ID as W, DOUBAO_MODELS as X, DOUBAO_MAX_TOKENS as Y, DOUBAO_PROVIDER as Z, StreamCallbacks as _, findReasoningLevel as _t, DEFAULT_BOT_ID as a, DoubaoReasoningLevel as at, TOOL_LOCAL_UPLOAD_ENDPOINT as b, needDeepThinkValue as bt, DoubaoChatResult as c, SKILL_CARRIER_MODEL_ID as ct, DoubaoMessage as d, TASK_RUNTIME_LOCAL_PC as dt, DOUBAO_SKILLS as et, DoubaoUpstreamError as f, TASK_SANDBOX_AUTH_ALLOW_ALL as ft, RUNTIME_VERSION as g, findDoubaoModel as gt, QUOTA_ENDPOINT as h, enabledModelsOf as ht, ChatRequestOptions as i, DoubaoModelInfo as it, extractModel as j, saveBrowserCredentials as jt, collectBlocks as k, loadBrowserCredentials as kt, DoubaoErrorKind as l, TASK_AGENT_MODE as lt, DoubaoUsage as m, doubaoCatalogEntries as mt, CHAT_ENDPOINT as n, DiscoveredDoubaoModel as nt, DOUBAO_ERROR_HINTS as o, DoubaoSkillName as ot, DoubaoUpstreamErrorMeta as p, discoverDoubaoModels as pt, DOUBAO_IMAGE_MODEL_ID as q, CLIENT_PARAMS as r, DoubaoCatalogEntry as rt, DOUBAO_VERSION as s, NO_THINKING_MODEL_IDS as st, ACCOUNT_ENDPOINT as t, DOUBAO_UNAVAILABLE_MODELS as tt, DoubaoImage as u, TASK_RUNTIME_CLOUD_VM as ut, TOOL_LOCAL_ACK_ENDPOINT as v, inputSkillOf as vt, buildGeneralTaskParam as w, REQUIRED_COOKIE_NAMES as wt, applyRenewals as x, supportsReasoning as xt, TOOL_LOCAL_COMPLETE_ENDPOINT as y, isTaskModel as yt, withImagePrefix as z };
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as DOUBAO_SKILLS, A as describeDoubaoFailure, At as saveBrowserCredentials, B as CREATION_BLOCK_TYPE, C as buildChatBody, Ct as REQUIRED_COOKIE_NAMES, D as chat, Dt as invalidateCredentialCache, E as buildQueryUrl, Et as hasBrowserCredentials, F as probeAccount, G as DOUBAO_DEFAULT_MODEL_ID, H as DEEP_THINK_ON, I as streamChat, J as DOUBAO_MAX_TOKENS, K as DOUBAO_IMAGE_MODEL_ID, L as taskModeEnabled, M as invalidateRenewals, N as isRetryableFailure, O as classifyDoubaoFailure, Ot as loadBrowserCredentials, P as parseFrames, Q as DOUBAO_REASONING_LEVELS, R as taskWorkspaceOf, S as assembleReplyText, St as DoubaoCredentials, T as buildHeaders, Tt as clearCredentialCache, U as DEFAULT_REASONING_LEVEL_ID, V as DEEP_THINK_OFF, W as DOUBAO_CONTEXT_WINDOW, X as DOUBAO_PROVIDER, Y as DOUBAO_MODELS, Z as DOUBAO_PROVIDER_DISPLAY_NAME, _ as StreamCallbacks, _t as inputSkillOf, a as DEFAULT_BOT_ID, at as DoubaoSkillName, b as TOOL_LOCAL_UPLOAD_ENDPOINT, bt as supportsReasoning, c as DoubaoChatResult, ct as TASK_AGENT_MODE, d as DoubaoMessage, dt as TASK_SANDBOX_AUTH_ALLOW_ALL, et as DOUBAO_UNAVAILABLE_MODELS, f as DoubaoUpstreamError, ft as discoverDoubaoModels, g as RUNTIME_VERSION, gt as findReasoningLevel, h as QUOTA_ENDPOINT, ht as findDoubaoModel, i as ChatRequestOptions, it as DoubaoReasoningLevel, j as extractModel, k as collectBlocks, kt as loadDoubaoCredentials, l as DoubaoErrorKind, lt as TASK_RUNTIME_CLOUD_VM, m as DoubaoUsage, mt as enabledModelsOf, n as CHAT_ENDPOINT, nt as DoubaoCatalogEntry, o as DOUBAO_ERROR_HINTS, ot as NO_THINKING_MODEL_IDS, p as DoubaoUpstreamErrorMeta, pt as doubaoCatalogEntries, q as DOUBAO_IMAGE_MODEL_NAME, r as CLIENT_PARAMS, rt as DoubaoModelInfo, s as DOUBAO_VERSION, st as SKILL_CARRIER_MODEL_ID, t as ACCOUNT_ENDPOINT, tt as DiscoveredDoubaoModel, u as DoubaoImage, ut as TASK_RUNTIME_LOCAL_PC, v as TOOL_LOCAL_ACK_ENDPOINT, vt as isTaskModel, w as buildGeneralTaskParam, wt as clearBrowserCredentials, x as applyRenewals, xt as CREDENTIAL_TTL_MS, y as TOOL_LOCAL_COMPLETE_ENDPOINT, yt as needDeepThinkValue, z as CHAT_AGENT_MODE } from "./doubao-upstream-CJpMsaTX.js";
1
+ import { $ as DOUBAO_REASONING_LEVELS, A as describeDoubaoFailure, At as loadDoubaoCredentials, B as CHAT_AGENT_MODE, C as buildChatBody, Ct as DoubaoCredentials, D as chat, Dt as hasBrowserCredentials, E as buildQueryUrl, Et as clearCredentialCache, F as probeAccount, G as DOUBAO_CONTEXT_WINDOW, H as DEEP_THINK_OFF, I as streamChat, J as DOUBAO_IMAGE_MODEL_NAME, K as DOUBAO_DEFAULT_MODEL_ID, L as taskModeEnabled, M as invalidateRenewals, N as isRetryableFailure, O as classifyDoubaoFailure, Ot as invalidateCredentialCache, P as parseFrames, Q as DOUBAO_PROVIDER_DISPLAY_NAME, R as taskWorkspaceOf, S as assembleReplyText, St as CREDENTIAL_TTL_MS, T as buildHeaders, Tt as clearBrowserCredentials, U as DEEP_THINK_ON, V as CREATION_BLOCK_TYPE, W as DEFAULT_REASONING_LEVEL_ID, X as DOUBAO_MODELS, Y as DOUBAO_MAX_TOKENS, Z as DOUBAO_PROVIDER, _ as StreamCallbacks, _t as findReasoningLevel, a as DEFAULT_BOT_ID, at as DoubaoReasoningLevel, b as TOOL_LOCAL_UPLOAD_ENDPOINT, bt as needDeepThinkValue, c as DoubaoChatResult, ct as SKILL_CARRIER_MODEL_ID, d as DoubaoMessage, dt as TASK_RUNTIME_LOCAL_PC, et as DOUBAO_SKILLS, f as DoubaoUpstreamError, ft as TASK_SANDBOX_AUTH_ALLOW_ALL, g as RUNTIME_VERSION, gt as findDoubaoModel, h as QUOTA_ENDPOINT, ht as enabledModelsOf, i as ChatRequestOptions, it as DoubaoModelInfo, j as extractModel, jt as saveBrowserCredentials, k as collectBlocks, kt as loadBrowserCredentials, l as DoubaoErrorKind, lt as TASK_AGENT_MODE, m as DoubaoUsage, mt as doubaoCatalogEntries, n as CHAT_ENDPOINT, nt as DiscoveredDoubaoModel, o as DOUBAO_ERROR_HINTS, ot as DoubaoSkillName, p as DoubaoUpstreamErrorMeta, pt as discoverDoubaoModels, q as DOUBAO_IMAGE_MODEL_ID, r as CLIENT_PARAMS, rt as DoubaoCatalogEntry, s as DOUBAO_VERSION, st as NO_THINKING_MODEL_IDS, t as ACCOUNT_ENDPOINT, tt as DOUBAO_UNAVAILABLE_MODELS, u as DoubaoImage, ut as TASK_RUNTIME_CLOUD_VM, v as TOOL_LOCAL_ACK_ENDPOINT, vt as inputSkillOf, w as buildGeneralTaskParam, wt as REQUIRED_COOKIE_NAMES, x as applyRenewals, xt as supportsReasoning, y as TOOL_LOCAL_COMPLETE_ENDPOINT, yt as isTaskModel, z as withImagePrefix } from "./doubao-upstream-CAg0AS4T.js";
2
2
  import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
3
3
  import { IncomingMessage, ServerResponse } from "node:http";
4
4
  import z from "@deepseek-ai/schemastery";
@@ -616,4 +616,4 @@ declare const _default: {
616
616
  apply: typeof apply;
617
617
  };
618
618
  //#endregion
619
- export { ACCOUNT_ENDPOINT, CHAT_AGENT_MODE, CHAT_ENDPOINT, CLIENT_PARAMS, CREATION_BLOCK_TYPE, CREDENTIAL_TTL_MS, ChatRequestOptions, Config, DEEP_THINK_OFF, DEEP_THINK_ON, DEFAULT_BOT_ID, DEFAULT_REASONING_LEVEL_ID, DISCOVERY_TTL_MS, DOUBAO_AUTH_PATH, DOUBAO_CATALOG_PATH, DOUBAO_CONTEXT_WINDOW, DOUBAO_DEFAULT_MODEL_ID, DOUBAO_ERROR_HINTS, DOUBAO_IMAGE_MODEL_ID, DOUBAO_IMAGE_MODEL_NAME, DOUBAO_MAX_TOKENS, DOUBAO_MODELS, DOUBAO_PROVIDER, DOUBAO_PROVIDER_DISPLAY_NAME, DOUBAO_QUOTA_PATH, DOUBAO_REASONING_LEVELS, DOUBAO_SAVE_PATH, DOUBAO_SETTINGS_NS, DOUBAO_SKILLS, DOUBAO_STREAM_IDLE_TIMEOUT_MS, DOUBAO_UNAVAILABLE_MODELS, DOUBAO_VERSION, DiscoveredDoubaoModel, DoubaoCatalogEntry, DoubaoChatResult, DoubaoCredentials, DoubaoErrorKind, DoubaoImage, DoubaoMessage, DoubaoModelInfo, DoubaoPluginContext, type DoubaoProfileLocation, DoubaoQuota, DoubaoReasoningLevel, DoubaoSettings, type DoubaoShim, DoubaoSkillName, DoubaoUpstreamError, DoubaoUpstreamErrorMeta, DoubaoUsage, ENABLED_MODEL_IDS_FIELD, NO_THINKING_MODEL_IDS, PLUGIN_ID, PLUGIN_NAME, PROFILE_DIR_FIELD, PROFILE_ENV, type ProfileSource, QUOTA_ENDPOINT, QUOTA_TTL_MS, QuotaWindow, QuotaWindowType, REQUIRED_COOKIE_NAMES, RUNTIME_VERSION, SKILL_CARRIER_MODEL_ID, StreamCallbacks, TASK_AGENT_MODE, TASK_RUNTIME_CLOUD_VM, TASK_RUNTIME_LOCAL_PC, TASK_SANDBOX_AUTH_ALLOW_ALL, TOOL_EMULATION_FIELD, TOOL_LOCAL_ACK_ENDPOINT, TOOL_LOCAL_COMPLETE_ENDPOINT, TOOL_LOCAL_UPLOAD_ENDPOINT, apply, applyRenewals, assembleReplyText, buildChatBody, buildGeneralTaskParam, buildHeaders, buildQueryUrl, chat, classifyDoubaoFailure, clearBrowserCredentials, clearCredentialCache, collectBlocks, createDoubaoAdapter, createDoubaoShim, _default as default, describeDoubaoFailure, describeProfileLocation, discoverAllCachedModels, discoverDoubaoModels, discoverModels, doubaoCatalogEntries, doubaoQuotaView, effectiveIds, enabledIdsOf, enabledModelsOf, extractModel, extractUserDataDir, fetchQuota, findDoubaoModel, findDoubaoUserDataDir, findReasoningLevel, findWindow, formatDuration, hasBrowserCredentials, inject, inputSkillOf, invalidateCredentialCache, invalidateDiscovery, invalidateQuotaCache, invalidateRenewals, isConfigured, isRetryableFailure, isTaskModel, listDoubaoProfiles, liveModels, loadBrowserCredentials, loadDoubaoCredentials, looksLikeProfile, millisUntilReset, name, needDeepThinkValue, normalizeWindow, parseFrames, presentationDiag, probeAccount, profileDirOf, registerDoubaoAuthRoute, registerDoubaoCatalogRoute, registerDoubaoQuotaRoute, registerDoubaoSaveRoute, resolveUserProvided, saveBrowserCredentials, setProfileOverride, settingsNamespaceOf, streamChat, supportsReasoning, taskModeEnabled, taskWorkspaceOf, toolEmulationOf };
619
+ export { ACCOUNT_ENDPOINT, CHAT_AGENT_MODE, CHAT_ENDPOINT, CLIENT_PARAMS, CREATION_BLOCK_TYPE, CREDENTIAL_TTL_MS, ChatRequestOptions, Config, DEEP_THINK_OFF, DEEP_THINK_ON, DEFAULT_BOT_ID, DEFAULT_REASONING_LEVEL_ID, DISCOVERY_TTL_MS, DOUBAO_AUTH_PATH, DOUBAO_CATALOG_PATH, DOUBAO_CONTEXT_WINDOW, DOUBAO_DEFAULT_MODEL_ID, DOUBAO_ERROR_HINTS, DOUBAO_IMAGE_MODEL_ID, DOUBAO_IMAGE_MODEL_NAME, DOUBAO_MAX_TOKENS, DOUBAO_MODELS, DOUBAO_PROVIDER, DOUBAO_PROVIDER_DISPLAY_NAME, DOUBAO_QUOTA_PATH, DOUBAO_REASONING_LEVELS, DOUBAO_SAVE_PATH, DOUBAO_SETTINGS_NS, DOUBAO_SKILLS, DOUBAO_STREAM_IDLE_TIMEOUT_MS, DOUBAO_UNAVAILABLE_MODELS, DOUBAO_VERSION, DiscoveredDoubaoModel, DoubaoCatalogEntry, DoubaoChatResult, DoubaoCredentials, DoubaoErrorKind, DoubaoImage, DoubaoMessage, DoubaoModelInfo, DoubaoPluginContext, type DoubaoProfileLocation, DoubaoQuota, DoubaoReasoningLevel, DoubaoSettings, type DoubaoShim, DoubaoSkillName, DoubaoUpstreamError, DoubaoUpstreamErrorMeta, DoubaoUsage, ENABLED_MODEL_IDS_FIELD, NO_THINKING_MODEL_IDS, PLUGIN_ID, PLUGIN_NAME, PROFILE_DIR_FIELD, PROFILE_ENV, type ProfileSource, QUOTA_ENDPOINT, QUOTA_TTL_MS, QuotaWindow, QuotaWindowType, REQUIRED_COOKIE_NAMES, RUNTIME_VERSION, SKILL_CARRIER_MODEL_ID, StreamCallbacks, TASK_AGENT_MODE, TASK_RUNTIME_CLOUD_VM, TASK_RUNTIME_LOCAL_PC, TASK_SANDBOX_AUTH_ALLOW_ALL, TOOL_EMULATION_FIELD, TOOL_LOCAL_ACK_ENDPOINT, TOOL_LOCAL_COMPLETE_ENDPOINT, TOOL_LOCAL_UPLOAD_ENDPOINT, apply, applyRenewals, assembleReplyText, buildChatBody, buildGeneralTaskParam, buildHeaders, buildQueryUrl, chat, classifyDoubaoFailure, clearBrowserCredentials, clearCredentialCache, collectBlocks, createDoubaoAdapter, createDoubaoShim, _default as default, describeDoubaoFailure, describeProfileLocation, discoverAllCachedModels, discoverDoubaoModels, discoverModels, doubaoCatalogEntries, doubaoQuotaView, effectiveIds, enabledIdsOf, enabledModelsOf, extractModel, extractUserDataDir, fetchQuota, findDoubaoModel, findDoubaoUserDataDir, findReasoningLevel, findWindow, formatDuration, hasBrowserCredentials, inject, inputSkillOf, invalidateCredentialCache, invalidateDiscovery, invalidateQuotaCache, invalidateRenewals, isConfigured, isRetryableFailure, isTaskModel, listDoubaoProfiles, liveModels, loadBrowserCredentials, loadDoubaoCredentials, looksLikeProfile, millisUntilReset, name, needDeepThinkValue, normalizeWindow, parseFrames, presentationDiag, probeAccount, profileDirOf, registerDoubaoAuthRoute, registerDoubaoCatalogRoute, registerDoubaoQuotaRoute, registerDoubaoSaveRoute, resolveUserProvided, saveBrowserCredentials, setProfileOverride, settingsNamespaceOf, streamChat, supportsReasoning, taskModeEnabled, taskWorkspaceOf, toolEmulationOf, withImagePrefix };
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as resolveUserProvided, A as extractModel, At as needDeepThinkValue, B as clearBrowserCredentials, C as buildGeneralTaskParam, Ct as discoverDoubaoModels, D as classifyDoubaoFailure, Dt as findReasoningLevel, E as chat, Et as findDoubaoModel, F as streamChat, G as loadDoubaoCredentials, H as hasBrowserCredentials, I as taskModeEnabled, J as describeProfileLocation, K as saveBrowserCredentials, L as taskWorkspaceOf, M as isRetryableFailure, N as parseFrames, O as collectBlocks, Ot as inputSkillOf, P as probeAccount, Q as looksLikeProfile, R as CREDENTIAL_TTL_MS, S as buildChatBody, St as TASK_SANDBOX_AUTH_ALLOW_ALL, T as buildQueryUrl, Tt as enabledModelsOf, U as invalidateCredentialCache, V as clearCredentialCache, W as loadBrowserCredentials, X as findDoubaoUserDataDir, Y as extractUserDataDir, Z as listDoubaoProfiles, _ as TOOL_LOCAL_ACK_ENDPOINT, _t as NO_THINKING_MODEL_IDS, a as invalidateQuotaCache, at as DEFAULT_REASONING_LEVEL_ID, b as applyRenewals, bt as TASK_RUNTIME_CLOUD_VM, c as ACCOUNT_ENDPOINT, ct as DOUBAO_IMAGE_MODEL_ID, d as DEFAULT_BOT_ID, dt as DOUBAO_MODELS, et as setProfileOverride, f as DOUBAO_ERROR_HINTS, ft as DOUBAO_PROVIDER, g as RUNTIME_VERSION, gt as DOUBAO_UNAVAILABLE_MODELS, h as QUOTA_ENDPOINT, ht as DOUBAO_SKILLS, i as formatDuration, it as DEEP_THINK_ON, j as invalidateRenewals, jt as supportsReasoning, k as describeDoubaoFailure, kt as isTaskModel, l as CHAT_ENDPOINT, lt as DOUBAO_IMAGE_MODEL_NAME, m as DoubaoUpstreamError, mt as DOUBAO_REASONING_LEVELS, n as fetchQuota, nt as CREATION_BLOCK_TYPE, o as millisUntilReset, ot as DOUBAO_CONTEXT_WINDOW, p as DOUBAO_VERSION, pt as DOUBAO_PROVIDER_DISPLAY_NAME, q as PROFILE_ENV, r as findWindow, rt as DEEP_THINK_OFF, s as normalizeWindow, st as DOUBAO_DEFAULT_MODEL_ID, t as QUOTA_TTL_MS, tt as CHAT_AGENT_MODE, u as CLIENT_PARAMS, ut as DOUBAO_MAX_TOKENS, v as TOOL_LOCAL_COMPLETE_ENDPOINT, vt as SKILL_CARRIER_MODEL_ID, w as buildHeaders, wt as doubaoCatalogEntries, x as assembleReplyText, xt as TASK_RUNTIME_LOCAL_PC, y as TOOL_LOCAL_UPLOAD_ENDPOINT, yt as TASK_AGENT_MODE, z as REQUIRED_COOKIE_NAMES } from "./doubao-quota-Bq-V97h9.js";
2
- import { _ as createDoubaoAdapter, a as doubaoQuotaView, c as registerDoubaoQuotaRoute, d as discoverAllCachedModels, f as discoverModels, g as DOUBAO_STREAM_IDLE_TIMEOUT_MS, h as createDoubaoShim, i as DOUBAO_SAVE_PATH, l as registerDoubaoSaveRoute, m as liveModels, n as DOUBAO_CATALOG_PATH, o as registerDoubaoAuthRoute, p as invalidateDiscovery, r as DOUBAO_QUOTA_PATH, s as registerDoubaoCatalogRoute, t as DOUBAO_AUTH_PATH, u as DISCOVERY_TTL_MS } from "./doubao-status-uEa8afa1.js";
1
+ import { $ as looksLikeProfile, A as extractModel, At as isTaskModel, B as REQUIRED_COOKIE_NAMES, C as buildGeneralTaskParam, Ct as TASK_SANDBOX_AUTH_ALLOW_ALL, D as classifyDoubaoFailure, Dt as findDoubaoModel, E as chat, Et as enabledModelsOf, F as streamChat, G as loadBrowserCredentials, H as clearCredentialCache, I as taskModeEnabled, J as PROFILE_ENV, K as loadDoubaoCredentials, L as taskWorkspaceOf, M as isRetryableFailure, Mt as supportsReasoning, N as parseFrames, O as collectBlocks, Ot as findReasoningLevel, P as probeAccount, Q as listDoubaoProfiles, R as withImagePrefix, S as buildChatBody, St as TASK_RUNTIME_LOCAL_PC, T as buildQueryUrl, Tt as doubaoCatalogEntries, U as hasBrowserCredentials, V as clearBrowserCredentials, W as invalidateCredentialCache, X as extractUserDataDir, Y as describeProfileLocation, Z as findDoubaoUserDataDir, _ as TOOL_LOCAL_ACK_ENDPOINT, _t as DOUBAO_UNAVAILABLE_MODELS, a as invalidateQuotaCache, at as DEEP_THINK_ON, b as applyRenewals, bt as TASK_AGENT_MODE, c as ACCOUNT_ENDPOINT, ct as DOUBAO_DEFAULT_MODEL_ID, d as DEFAULT_BOT_ID, dt as DOUBAO_MAX_TOKENS, et as resolveUserProvided, f as DOUBAO_ERROR_HINTS, ft as DOUBAO_MODELS, g as RUNTIME_VERSION, gt as DOUBAO_SKILLS, h as QUOTA_ENDPOINT, ht as DOUBAO_REASONING_LEVELS, i as formatDuration, it as DEEP_THINK_OFF, j as invalidateRenewals, jt as needDeepThinkValue, k as describeDoubaoFailure, kt as inputSkillOf, l as CHAT_ENDPOINT, lt as DOUBAO_IMAGE_MODEL_ID, m as DoubaoUpstreamError, mt as DOUBAO_PROVIDER_DISPLAY_NAME, n as fetchQuota, nt as CHAT_AGENT_MODE, o as millisUntilReset, ot as DEFAULT_REASONING_LEVEL_ID, p as DOUBAO_VERSION, pt as DOUBAO_PROVIDER, q as saveBrowserCredentials, r as findWindow, rt as CREATION_BLOCK_TYPE, s as normalizeWindow, st as DOUBAO_CONTEXT_WINDOW, t as QUOTA_TTL_MS, tt as setProfileOverride, u as CLIENT_PARAMS, ut as DOUBAO_IMAGE_MODEL_NAME, v as TOOL_LOCAL_COMPLETE_ENDPOINT, vt as NO_THINKING_MODEL_IDS, w as buildHeaders, wt as discoverDoubaoModels, x as assembleReplyText, xt as TASK_RUNTIME_CLOUD_VM, y as TOOL_LOCAL_UPLOAD_ENDPOINT, yt as SKILL_CARRIER_MODEL_ID, z as CREDENTIAL_TTL_MS } from "./doubao-quota-CAdK_fAm.js";
2
+ import { _ as createDoubaoAdapter, a as doubaoQuotaView, c as registerDoubaoQuotaRoute, d as discoverAllCachedModels, f as discoverModels, g as DOUBAO_STREAM_IDLE_TIMEOUT_MS, h as createDoubaoShim, i as DOUBAO_SAVE_PATH, l as registerDoubaoSaveRoute, m as liveModels, n as DOUBAO_CATALOG_PATH, o as registerDoubaoAuthRoute, p as invalidateDiscovery, r as DOUBAO_QUOTA_PATH, s as registerDoubaoCatalogRoute, t as DOUBAO_AUTH_PATH, u as DISCOVERY_TTL_MS } from "./doubao-status-gcSuFOQg.js";
3
3
  import { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { homedir } from "node:os";
5
5
  import { dirname, join } from "node:path";
@@ -494,4 +494,4 @@ var src_default = {
494
494
  apply
495
495
  };
496
496
  //#endregion
497
- export { ACCOUNT_ENDPOINT, CHAT_AGENT_MODE, CHAT_ENDPOINT, CLIENT_PARAMS, CREATION_BLOCK_TYPE, CREDENTIAL_TTL_MS, Config, DEEP_THINK_OFF, DEEP_THINK_ON, DEFAULT_BOT_ID, DEFAULT_REASONING_LEVEL_ID, DISCOVERY_TTL_MS, DOUBAO_AUTH_PATH, DOUBAO_CATALOG_PATH, DOUBAO_CONTEXT_WINDOW, DOUBAO_DEFAULT_MODEL_ID, DOUBAO_ERROR_HINTS, DOUBAO_IMAGE_MODEL_ID, DOUBAO_IMAGE_MODEL_NAME, DOUBAO_MAX_TOKENS, DOUBAO_MODELS, DOUBAO_PROVIDER, DOUBAO_PROVIDER_DISPLAY_NAME, DOUBAO_QUOTA_PATH, DOUBAO_REASONING_LEVELS, DOUBAO_SAVE_PATH, DOUBAO_SETTINGS_NS, DOUBAO_SKILLS, DOUBAO_STREAM_IDLE_TIMEOUT_MS, DOUBAO_UNAVAILABLE_MODELS, DOUBAO_VERSION, DoubaoUpstreamError, ENABLED_MODEL_IDS_FIELD, NO_THINKING_MODEL_IDS, PLUGIN_ID, PLUGIN_NAME, PROFILE_DIR_FIELD, PROFILE_ENV, QUOTA_ENDPOINT, QUOTA_TTL_MS, REQUIRED_COOKIE_NAMES, RUNTIME_VERSION, SKILL_CARRIER_MODEL_ID, TASK_AGENT_MODE, TASK_RUNTIME_CLOUD_VM, TASK_RUNTIME_LOCAL_PC, TASK_SANDBOX_AUTH_ALLOW_ALL, TOOL_EMULATION_FIELD, TOOL_LOCAL_ACK_ENDPOINT, TOOL_LOCAL_COMPLETE_ENDPOINT, TOOL_LOCAL_UPLOAD_ENDPOINT, apply, applyRenewals, assembleReplyText, buildChatBody, buildGeneralTaskParam, buildHeaders, buildQueryUrl, chat, classifyDoubaoFailure, clearBrowserCredentials, clearCredentialCache, collectBlocks, createDoubaoAdapter, createDoubaoShim, src_default as default, describeDoubaoFailure, describeProfileLocation, discoverAllCachedModels, discoverDoubaoModels, discoverModels, doubaoCatalogEntries, doubaoQuotaView, effectiveIds, enabledIdsOf, enabledModelsOf, extractModel, extractUserDataDir, fetchQuota, findDoubaoModel, findDoubaoUserDataDir, findReasoningLevel, findWindow, formatDuration, hasBrowserCredentials, inject, inputSkillOf, invalidateCredentialCache, invalidateDiscovery, invalidateQuotaCache, invalidateRenewals, isConfigured, isRetryableFailure, isTaskModel, listDoubaoProfiles, liveModels, loadBrowserCredentials, loadDoubaoCredentials, looksLikeProfile, millisUntilReset, name, needDeepThinkValue, normalizeWindow, parseFrames, presentationDiag, probeAccount, profileDirOf, registerDoubaoAuthRoute, registerDoubaoCatalogRoute, registerDoubaoQuotaRoute, registerDoubaoSaveRoute, resolveUserProvided, saveBrowserCredentials, setProfileOverride, settingsNamespaceOf, streamChat, supportsReasoning, taskModeEnabled, taskWorkspaceOf, toolEmulationOf };
497
+ export { ACCOUNT_ENDPOINT, CHAT_AGENT_MODE, CHAT_ENDPOINT, CLIENT_PARAMS, CREATION_BLOCK_TYPE, CREDENTIAL_TTL_MS, Config, DEEP_THINK_OFF, DEEP_THINK_ON, DEFAULT_BOT_ID, DEFAULT_REASONING_LEVEL_ID, DISCOVERY_TTL_MS, DOUBAO_AUTH_PATH, DOUBAO_CATALOG_PATH, DOUBAO_CONTEXT_WINDOW, DOUBAO_DEFAULT_MODEL_ID, DOUBAO_ERROR_HINTS, DOUBAO_IMAGE_MODEL_ID, DOUBAO_IMAGE_MODEL_NAME, DOUBAO_MAX_TOKENS, DOUBAO_MODELS, DOUBAO_PROVIDER, DOUBAO_PROVIDER_DISPLAY_NAME, DOUBAO_QUOTA_PATH, DOUBAO_REASONING_LEVELS, DOUBAO_SAVE_PATH, DOUBAO_SETTINGS_NS, DOUBAO_SKILLS, DOUBAO_STREAM_IDLE_TIMEOUT_MS, DOUBAO_UNAVAILABLE_MODELS, DOUBAO_VERSION, DoubaoUpstreamError, ENABLED_MODEL_IDS_FIELD, NO_THINKING_MODEL_IDS, PLUGIN_ID, PLUGIN_NAME, PROFILE_DIR_FIELD, PROFILE_ENV, QUOTA_ENDPOINT, QUOTA_TTL_MS, REQUIRED_COOKIE_NAMES, RUNTIME_VERSION, SKILL_CARRIER_MODEL_ID, TASK_AGENT_MODE, TASK_RUNTIME_CLOUD_VM, TASK_RUNTIME_LOCAL_PC, TASK_SANDBOX_AUTH_ALLOW_ALL, TOOL_EMULATION_FIELD, TOOL_LOCAL_ACK_ENDPOINT, TOOL_LOCAL_COMPLETE_ENDPOINT, TOOL_LOCAL_UPLOAD_ENDPOINT, apply, applyRenewals, assembleReplyText, buildChatBody, buildGeneralTaskParam, buildHeaders, buildQueryUrl, chat, classifyDoubaoFailure, clearBrowserCredentials, clearCredentialCache, collectBlocks, createDoubaoAdapter, createDoubaoShim, src_default as default, describeDoubaoFailure, describeProfileLocation, discoverAllCachedModels, discoverDoubaoModels, discoverModels, doubaoCatalogEntries, doubaoQuotaView, effectiveIds, enabledIdsOf, enabledModelsOf, extractModel, extractUserDataDir, fetchQuota, findDoubaoModel, findDoubaoUserDataDir, findReasoningLevel, findWindow, formatDuration, hasBrowserCredentials, inject, inputSkillOf, invalidateCredentialCache, invalidateDiscovery, invalidateQuotaCache, invalidateRenewals, isConfigured, isRetryableFailure, isTaskModel, listDoubaoProfiles, liveModels, loadBrowserCredentials, loadDoubaoCredentials, looksLikeProfile, millisUntilReset, name, needDeepThinkValue, normalizeWindow, parseFrames, presentationDiag, probeAccount, profileDirOf, registerDoubaoAuthRoute, registerDoubaoCatalogRoute, registerDoubaoQuotaRoute, registerDoubaoSaveRoute, resolveUserProvided, saveBrowserCredentials, setProfileOverride, settingsNamespaceOf, streamChat, supportsReasoning, taskModeEnabled, taskWorkspaceOf, toolEmulationOf, withImagePrefix };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-doubao",
3
3
  "displayName": "DSH Connect Doubao",
4
4
  "description": "把豆包(Doubao)账号接入 DeepSeek Harness:对话模型与「工作任务」模型(2.1 Lite / 2.1 Pro / 自动,走会员付费额度)、Seedream 生图、以及默认开启的深度思考,外加一块只读额度看板(5 小时 / 周 / 活动赠送)。只需浏览器扫码登录一次;仅 Windows x64,会话用 DPAPI 密封在本机。",
5
- "version": "0.5.0",
5
+ "version": "0.6.0",
6
6
  "license": "MIT",
7
7
  "keywords": [
8
8
  "dsh-plugin",