dsh-vision-router 1.6.0 → 1.6.2
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/README.md +3 -3
- package/README.zh.md +2 -2
- package/cordis.patch.yml +10 -5
- package/docs/handover-178.zh-CN.md +116 -0
- package/entry.js +67 -12
- package/index.js +468 -146
- package/lib/adapter-update-coalescer.js +74 -0
- package/lib/client.js +700 -317
- package/lib/depth-guidance.js +109 -0
- package/lib/dsh-contract-compat.js +184 -0
- package/lib/image-resource-governor.js +215 -0
- package/lib/mixed-router.js +143 -0
- package/lib/pixel-diff-stream.js +143 -0
- package/lib/session-vision-state.js +400 -0
- package/lib/structured-bootstrap.js +34 -3
- package/lib/structured-flow-hardening.js +388 -0
- package/lib/tesseract-exec-compat.js +146 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
<p align="center">💬 <strong>QQ community group: 1105463028</strong></p>
|
|
30
30
|
|
|
31
31
|
> [!WARNING]
|
|
32
|
-
> 📌 **Announcement (v1.6.
|
|
32
|
+
> 📌 **Announcement (v1.6.2)**
|
|
33
33
|
>
|
|
34
|
-
> **v1.6.
|
|
34
|
+
> **v1.6.2:** Stability release — fixes onboarding, OCR, model synchronization and large-image handling, improving long-session and overall runtime reliability.
|
|
35
35
|
|
|
36
36
|
<p align="center">
|
|
37
37
|
<img src="assets/vision-demo.gif" width="640" alt="Demo: paste an image, the agent locates the send button with vision_ground / vision_crop / vision_pixel_diff and answers with coordinates" />
|
|
@@ -154,7 +154,7 @@ The auto-vision group follows the live DSH model catalog. Adding models or chang
|
|
|
154
154
|
|
|
155
155
|
### 3. Paste or upload the image
|
|
156
156
|
|
|
157
|
-
After choosing the “+ Auto Vision” group, paste or upload an image normally. By default the complete vision tool schema is stable from session start, so the agent can immediately use `vision_describe`, `vision_ground`, `vision_crop`, and the rest across multiple steps when needed.
|
|
157
|
+
After choosing the “+ Auto Vision” model group, paste or upload an image normally. By default the complete vision tool schema is stable from session start, so the agent can immediately use `vision_describe`, `vision_ground`, `vision_crop`, and the rest across multiple steps when needed.
|
|
158
158
|
|
|
159
159
|
The built-in anonymous OVH vision fallback is already configured, so normal image use needs no signup or API key. **The lower-right chat picker selects only the brain/conversation model**; vision backends do not belong there. Advanced options live under **Settings → Plugins → Plugin config → 视觉路由(自动识图)**: each vision-backend row may select any callable generative user model already configured under **Settings → Models**. DSH image-capability metadata is advisory only: undeclared or text-only-labelled models remain selectable and show a warning. At runtime Vision Router always tries the provider's registered DSH adapter first — including WebSocket, RPC and private transports — and falls through on a real failure. The direct compatibility bridge is used only when an http(s) OpenAI Chat Completions endpoint is positively identified. Leaving every user row empty is valid; the OVH chain remains the final fallback. `Vision HTTP` is an internal transport route, not a model group users should select.
|
|
160
160
|
|
package/README.zh.md
CHANGED
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
<p align="center">💬 <strong>QQ 用户交流群:1105463028</strong></p>
|
|
30
30
|
|
|
31
31
|
> [!WARNING]
|
|
32
|
-
> 📌 **公告(v1.6.
|
|
32
|
+
> 📌 **公告(v1.6.2)**
|
|
33
33
|
>
|
|
34
|
-
> **v1.6.
|
|
34
|
+
> **v1.6.2:集中修复引导、OCR、模型同步与大图处理问题,提升长会话和整体运行稳定性。**
|
|
35
35
|
|
|
36
36
|
<p align="center">
|
|
37
37
|
<img src="assets/vision-demo.gif" width="640" alt="演示:粘贴图片,Agent 用 vision_ground / vision_crop / vision_pixel_diff 定位发送按钮并给出坐标" />
|
package/cordis.patch.yml
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
# without any manual cordis.patch.yml edits. Later layers (the profile's own
|
|
5
5
|
# cordis.patch.yml, --patch overlays) override these rows by id.
|
|
6
6
|
|
|
7
|
-
# 纯增量补丁(issue #34
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# 纯增量补丁(issue #34):不碰核心行。DSH rc.6仍保留旧版隐身接管兼容路径;
|
|
8
|
+
# DSH rc.7则始终由宿主拥有deepseek-official,插件只提供「+ 自动识图」包装路由。
|
|
9
|
+
# 因此这里永远不默认禁用官方llm-deepseek行。
|
|
10
10
|
|
|
11
11
|
# 挂载插件行。默认保持完整视觉工具表常驻(issue #81):虽然渐进挂载可以
|
|
12
12
|
# 少发一小段工具 schema,但图片轮首次扩展工具列表会改变请求前缀,可能让
|
|
@@ -18,8 +18,13 @@
|
|
|
18
18
|
config:
|
|
19
19
|
progressiveTools: false
|
|
20
20
|
|
|
21
|
-
#
|
|
22
|
-
#
|
|
21
|
+
# 放宽附件图片限制(宿主默认 5MB / 4000 万像素 → 20MB / 1 亿像素),
|
|
22
|
+
# 超长聊天记录截图(vision_long_screenshot_ocr 主场景)与大尺寸设计稿/
|
|
23
|
+
# 扫描图可过宿主准入。rc6 与 rc7 的 @deepseek-ai/dsh-attachment-local
|
|
24
|
+
# 均接受这两个可选字段(0.1.0-rc.6 / 0.1.0-rc.7 schema 已核对),且两边
|
|
25
|
+
# dsh-base bundle 都存在 `- id: attachment-local` 行,因此该补丁在两个
|
|
26
|
+
# 运行时上都有效、不破坏 host-neutral 原则;字段可选,不需要可在 profile
|
|
27
|
+
# 补丁层覆写。
|
|
23
28
|
- id: attachment-local
|
|
24
29
|
config:
|
|
25
30
|
maxImageBytes: 20971520
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# #178 交接文档:1+x 深挖引导(mixed 分路 / 深度档位 / 收敛分类 / 引导可配置)
|
|
2
|
+
|
|
3
|
+
> 对应 PR:[#178 feat: 1+x deep-dive guidance - mixed branching, depth tier, convergent classification, configurable copy](https://github.com/ysr666/dsh-vision-router/pull/178)
|
|
4
|
+
> 分支:`feat/mixed-router` @ `7ac5ee8`(stacked on #177 `feat/free-cloud-first` @ `a8384ca`)
|
|
5
|
+
> 作者:shaoqiuyuavailable(`rangsic2963277@163.com`)
|
|
6
|
+
> 状态:open,7 个 commit 全部为作者本人提交(2 个来自 #177 + 5 个本 PR 增量)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 一、一句话定位
|
|
11
|
+
|
|
12
|
+
在群主 v2 能力路由(#142)与 structured bootstrap 1+x(#136)框架之上,补齐**深挖阶段**的四个维度:**精度(mixed 分路)、深度(档位)、收敛(schema 分类)、可配置(引导文案)**。全部默认行为不变(zero-regression)。
|
|
13
|
+
|
|
14
|
+
## 二、增量作者与来源
|
|
15
|
+
|
|
16
|
+
| 项 | 说明 |
|
|
17
|
+
|---|---|
|
|
18
|
+
| 增量作者 | shaoqiuyuavailable,dsh-vision 插件(`shaoqiuyuavailable/text-llm-vision`)作者 |
|
|
19
|
+
| 概念来源 | dsh-vision main 分支的 `scan → zoom → guess` 场景路由 + PRECISION 档位;dsh-vision 分支(text-llm-vision)的场景级识图路由层设计 |
|
|
20
|
+
| 本 PR 性质 | 在群主已有框架上的**成本/速度妥协优化**:概念移植为 router 生态的轻量实现,不引入 dsh-vision 的完整引擎路由表 |
|
|
21
|
+
| 定位边界 | 与 #142(能力路由:谁来看)正交——本 PR 只负责**怎么看的引导**,出口选择仍归模型(软路由) |
|
|
22
|
+
|
|
23
|
+
## 三、设计哲学(四条,均来自 dsh-vision 实践结论)
|
|
24
|
+
|
|
25
|
+
1. **场景感知路由(scene-aware routing)**:先分类、再引导识别方式,替代"所有图一条固定链"。
|
|
26
|
+
2. **档位只定深度、不参与提示词组合**:fast/standard/deep 是用户级全局开关;引导文案是**模板集合**(每类一条),不是提示词矩阵——工作量 = 引导表 + 拼接函数。
|
|
27
|
+
3. **收敛分类(schema 免费收敛)**:让视觉模型直接输出结构化枚举(JSON schema 天然校验),替代系统启发式——同时用于 `content_kind`(主体)与 `mixed_of`(混合构成),删除约 60 行 entities 启发式。
|
|
28
|
+
4. **软引导、硬上限(soft guidance, hard caps)**:识别方式/工具选择归模型(软文案引导,保留逃生通道);深度是唯一硬约束(VISION_DEPTH_LIMIT)。
|
|
29
|
+
|
|
30
|
+
## 四、功能详述(5 个增量 commit)
|
|
31
|
+
|
|
32
|
+
### 1. `7fe43fb` feat: mixed branch routing(新建 `lib/mixed-router.js`)
|
|
33
|
+
- **动机**:1.5.3 中 bootstrap 判出 `visual_kind=mixed` 后无后续处理,模型自由深挖可能漏判/错判另一半内容(§4.6 缺陷实证)。
|
|
34
|
+
- **实现**:`planMixedBranches()` 消费 bootstrap 的 `mixed_of`,产出 ≤2 个分支(`MAX_MIXED_BRANCHES=2`),每分支一条独立软引导(`BRANCH_GUIDANCE`:document:code / document:form / document:table / ui / code / table / _default 放行);主/次分支按信号强度排序(可交互 > 文字 > 其余,`KIND_PRIORITY`)。
|
|
35
|
+
- **防呆**:`mixed_of` 缺失/为空 → `fallback=true` **放行**(绝不硬拦,行为同现状)。
|
|
36
|
+
- **成本**:混合图 ≤2 次视觉调用,成本封顶(副产品)。
|
|
37
|
+
- **语义差异**:与 dsh-vision 不同——语义从"实体主体"(人+飞机)改为"内容类型"(文档+UI)。
|
|
38
|
+
|
|
39
|
+
### 2. `a85c8c1` feat: visionDepth tier(新建 `lib/depth-guidance.js` + index.js 档位注入)
|
|
40
|
+
- **动机**:深挖深度无约束,成本不可控。
|
|
41
|
+
- **实现**:新配置 `visionDepth`(`fast|standard|deep`,默认 `standard`)。档位句注入 bootstrapReminder(执行前,只给档位)与 followupReminder(完成后,场景引导+档位句)。
|
|
42
|
+
- **硬上限**:`depthLimitFor()` — fast=1、deep=4、standard=不硬拦(现状行为)。在 evidence 深挖工具(`structuredFollowupEvidenceTools`)入口计数 `state.deepCalls`,超限返回 `VISION_DEPTH_LIMIT`(retryable:false)。bootstrap 那 1 遍不计入。
|
|
43
|
+
- **提示**:fast 档携带"若需深度定向识别请告知用户升级档位"句(搬 dsh-vision 回答节思想)。
|
|
44
|
+
|
|
45
|
+
### 3. `ff0ecca` feat: content_kind in bootstrap schema(`lib/structured-bootstrap.js`)
|
|
46
|
+
- **动机**:general 图(媒介无引导)缺主体方向,深挖无的放矢。
|
|
47
|
+
- **实现**:bootstrap schema 新增 `content_kind` 枚举(person/animal/plant/food/vehicle/machine/architecture/object/scene/meme + unknown),normalizer 枚举校验,非法/缺失 → unknown;media-kind 图(document/ui/code/chat)约定 unknown。
|
|
48
|
+
- **消费**:`renderDepthGuidance()` — general 且 content_kind 已知 → 内容引导(`CONTENT_GUIDANCE` 10 类);未知 → `GENERAL_FALLBACK_GUIDANCE` 兜底(让模型自判主体方向)。
|
|
49
|
+
|
|
50
|
+
### 4. `1b8b50e` refactor: mixed_of in bootstrap schema(`lib/structured-bootstrap.js` + `lib/mixed-router.js`)
|
|
51
|
+
- **动机**:entities 启发式推断混合构成不稳定。
|
|
52
|
+
- **实现**:bootstrap schema 新增 `mixed_of`(仅 `visual_kind=mixed` 时填写,1-2 项,document/ui/code/chat/general);normalizer 枚举校验+去重+≤2,非法/缺失 → `[]`(调用方 fallback 放行)。`normalizeMixedOf()` 与 schema 同域、同哲学,删除 entities 启发式路径(约 60 行)。
|
|
53
|
+
|
|
54
|
+
### 5. `7ac5ee8` feat: guidanceOverrides(`lib/client.js` + `lib/depth-guidance.js`)
|
|
55
|
+
- **动机**:引导文案硬编码,用户无法按需调整。
|
|
56
|
+
- **实现**:新配置 `guidanceOverrides`(`[{kind, text}]`,默认 `[]`= 内置表,零变化)。`resolveGuidance()` 覆盖优先于内置表;kind 覆盖场景(visual_kind:code/document/ui/chat)与内容(content_kind:person/…/meme)共 14 类。
|
|
57
|
+
- **UI**:设置卡片 Performance 组新增 `selectField`(visionDepth 下拉)+ `guidanceOverridesEditor`(行编辑器:类别 select + 文案 input + 移除 + 添加),zh/en 双语文案,`SELECT_KEYS` 校验。
|
|
58
|
+
|
|
59
|
+
## 五、mixed 变更说明(变更前后对比)
|
|
60
|
+
|
|
61
|
+
| 环节 | 变更前(1.5.3 / main) | 变更后(本分支) |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| bootstrap 判定 mixed 后 | 无后续处理,模型自由深挖(可能漏判/错判另一半内容) | 按 `mixed_of` 拆 ≤2 分支(`MAX_MIXED_BRANCHES=2`),各分支独立软引导;主/次按信号强度排序(ui > document > code > table > chat > general) |
|
|
64
|
+
| 混合构成判定来源 | 无(schema 无此字段) | `mixed_of`:schema 枚举,视觉模型直接输出;normalizer 校验去重 + ≤2 |
|
|
65
|
+
| 细分失败(mixed_of 缺失/为空) | 无细分(等同现状) | `fallback=true` **放行**(绝不硬拦,行为同现状) |
|
|
66
|
+
| 分支引导 | 无 | `BRANCH_GUIDANCE`:document:code/form/table → 逐字专精;ui → detect/ground;code → 逐字;table → 结构优先;_default → 放行 |
|
|
67
|
+
| 成本 | 混合图深挖轮数无上限 | ≤2 分支 = 混合图 ≤2 次识别调用(成本封顶,副产品) |
|
|
68
|
+
| 判定结果消费 | 无 | `bootstrapState.mixedPlan` → followupReminder 注入分支引导文案 |
|
|
69
|
+
|
|
70
|
+
原则:**精度优化**(避免漏判/错判另一半内容),成本封顶是副产品;所有分支引导都是软引导,模型保留逃生通道(软路由成立结论:不硬拦截识别方式)。
|
|
71
|
+
|
|
72
|
+
## 六、判定接口(供 #142 能力路由对接参考)
|
|
73
|
+
|
|
74
|
+
bootstrap 结构化输出新增两个字段,normalizer 已校验:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"visual_kind": "chat|document|ui|code|general|mixed|unknown",
|
|
79
|
+
"content_kind": "person|animal|plant|food|vehicle|machine|architecture|object|scene|meme|unknown",
|
|
80
|
+
"mixed_of": ["document|ui|code|chat|general"] // 仅 visual_kind=mixed,1-2 项
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- `content_kind` = **内容主体**(物理实体类,11 值含 unknown);`visual_kind` = **媒介**(正交维度)。
|
|
85
|
+
- `mixed_of` = **混合构成**(媒介组合,≤2),已去重排序(可交互 > 文字 > 其余)。
|
|
86
|
+
- 二者都是"schema 免费收敛"产物:视觉模型 JSON 输出 + normalizer 枚举校验,无启发式。
|
|
87
|
+
- 消费点:`bootstrapState.visualKind / contentKind / mixedPlan`(turn 状态),下一次 pre-step 的 followupReminder 按场景/内容/分支注入引导。
|
|
88
|
+
|
|
89
|
+
## 七、默认行为与零回归
|
|
90
|
+
|
|
91
|
+
| 开关 | 默认 | 关闭时行为 |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `visionDepth` | `standard` | 无硬上限,仅提示词引导(与现状等价) |
|
|
94
|
+
| `guidanceOverrides` | `[]` | 内置引导表(与现状等价) |
|
|
95
|
+
| mixed 分路 | 随 bootstrap 自动生效 | `mixed_of` 缺失 → fallback 放行(与现状等价) |
|
|
96
|
+
| `content_kind` | 新增字段 | 只影响 general 图引导(其余场景不消费) |
|
|
97
|
+
|
|
98
|
+
回归门:`tests/zero-regression-gate.test.js`(含 #177 的 orderedHttpProviders 默认关断言)+ 全量 407 pass / 0 fail / 6 skipped(env 相关)。
|
|
99
|
+
|
|
100
|
+
## 八、与 #142 / #177 的关系
|
|
101
|
+
|
|
102
|
+
- **与 #142 正交**:#142 管"哪个能力 → 哪个后端"(谁来看);本 PR 管"怎么看的引导"(怎么看)。判定结果(content_kind/mixed_of)可直接作为 #142 能力声明的输入(见第六节)。
|
|
103
|
+
- **stacked 依赖**:本分支含 #177 的 2 个 commit(freeCloudFirst + OCR 提示词强化)。合并顺序:先 #177 后 #178,或 #178 单独 squash(内含 177)。
|
|
104
|
+
|
|
105
|
+
## 九、测试
|
|
106
|
+
|
|
107
|
+
- 新增 `tests/mixed-router.test.js`(13 例:normalizeMixedOf 校验/去重/封顶/排序、buildMixedBranches 去重/封顶/单分支、mixedGuidance 精确→kind→放行、planMixedBranches fallback 防呆、renderMixedGuidance 文案)。
|
|
108
|
+
- 新增 `tests/depth-tier.test.js`(15 例:depthLimitFor fast/deep/standard、场景/内容引导查表与放行、renderDepthGuidance 拼接、guidanceOverrides 覆盖优先)。
|
|
109
|
+
- `tests/structured-bootstrap.test.js` +29 行(content_kind/mixed_of 枚举校验)。
|
|
110
|
+
- `package.json` test 脚本挂载两个新测试文件。
|
|
111
|
+
|
|
112
|
+
## 十、评审与合并指南(给群主)
|
|
113
|
+
|
|
114
|
+
1. 先审 #177(freeCloudFirst + OCR 提示词强化),再审本 PR;或合并时 squash。
|
|
115
|
+
2. 重点看三处:`lib/mixed-router.js` 的 fallback 防呆(绝不放行变成硬拦)、`index.js` 的 `VISION_DEPTH_LIMIT` 计数(bootstrap 不计入、只数 evidence 深挖工具)、`lib/depth-guidance.js` 的 `resolveGuidance`(覆盖优先)。
|
|
116
|
+
3. 判定接口(第六节)可直接对接 #142 能力声明,作者可协助整理接口说明。
|
package/entry.js
CHANGED
|
@@ -14,14 +14,36 @@ import { installAdversarialHardening } from './lib/adversarial-hardening.js'
|
|
|
14
14
|
import { installLocalVisionStabilizer } from './lib/local-vision-stabilizer.js'
|
|
15
15
|
import { installWrapperDirectoryAlias } from './lib/wrapper-directory.js'
|
|
16
16
|
import { installAndroidAttachmentCompat } from './lib/android-attachment-compat.js'
|
|
17
|
+
import { contextWithCoalescedAdapterUpdates } from './lib/adapter-update-coalescer.js'
|
|
18
|
+
import { installTesseractExecFileCompat } from './lib/tesseract-exec-compat.js'
|
|
19
|
+
import {
|
|
20
|
+
installStructuredFlowHardening,
|
|
21
|
+
normalizeGuidanceOverrides,
|
|
22
|
+
} from './lib/structured-flow-hardening.js'
|
|
23
|
+
import {
|
|
24
|
+
attachmentContextForContract,
|
|
25
|
+
installRc7SettingsCompatibility,
|
|
26
|
+
isRc7ContractRuntime,
|
|
27
|
+
protectRc7ProviderOwnership,
|
|
28
|
+
} from './lib/dsh-contract-compat.js'
|
|
17
29
|
|
|
18
30
|
// Schemastery object schemas expose set() as the supported way to replace a
|
|
19
31
|
// field schema. This mutates the Config object that index.js itself later uses
|
|
20
32
|
// for the settings namespace, so composition config and settings validation
|
|
21
33
|
// agree on the same default.
|
|
22
34
|
core.Config.set('progressiveTools', z.boolean().default(false))
|
|
35
|
+
// Structured 1+x now also has a turn-level wall-clock budget. Individual
|
|
36
|
+
// visionTaskTimeoutMs budgets remain unchanged; this one prevents a deep turn
|
|
37
|
+
// from multiplying them into several minutes of serial waiting.
|
|
38
|
+
core.Config.set('visionTurnBudgetMs', z.number().step(1000).min(10000).max(600000).default(90000))
|
|
23
39
|
|
|
24
40
|
export * from './index.js'
|
|
41
|
+
export {
|
|
42
|
+
attachmentContextForContract,
|
|
43
|
+
installRc7SettingsCompatibility,
|
|
44
|
+
isRc7ContractRuntime,
|
|
45
|
+
protectRc7ProviderOwnership,
|
|
46
|
+
} from './lib/dsh-contract-compat.js'
|
|
25
47
|
export const Config = core.Config
|
|
26
48
|
|
|
27
49
|
// Defense in depth for direct/programmatic callers that invoke apply() without
|
|
@@ -58,11 +80,47 @@ export function apply(ctx, config = {}) {
|
|
|
58
80
|
hardenedConfig,
|
|
59
81
|
core,
|
|
60
82
|
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
83
|
+
const runtimeConfig = {
|
|
84
|
+
...bootConfig,
|
|
85
|
+
progressiveTools: hardenedConfig.progressiveTools === true,
|
|
86
|
+
guidanceOverrides: normalizeGuidanceOverrides(bootConfig.guidanceOverrides ?? hardenedConfig.guidanceOverrides),
|
|
87
|
+
visionTurnBudgetMs:
|
|
88
|
+
Number.isFinite(Number(bootConfig.visionTurnBudgetMs))
|
|
89
|
+
? Number(bootConfig.visionTurnBudgetMs)
|
|
90
|
+
: 90000,
|
|
91
|
+
}
|
|
92
|
+
const rc7 = isRc7ContractRuntime(stabilizedCtx)
|
|
93
|
+
const ownershipCtx = rc7 ? protectRc7ProviderOwnership(stabilizedCtx) : stabilizedCtx
|
|
94
|
+
const settingsCtx = rc7
|
|
95
|
+
? installRc7SettingsCompatibility(ownershipCtx, { ...runtimeConfig, stealth: false }, {
|
|
96
|
+
namespace: 'vision-router',
|
|
97
|
+
Config: core.Config,
|
|
98
|
+
})
|
|
99
|
+
: ownershipCtx
|
|
100
|
+
// rc.6/Termux keeps the narrow process-local fallback that was required by
|
|
101
|
+
// the old attachment-local durability walk. rc.7 formalizes AttachmentId as
|
|
102
|
+
// store-owned, so never synthesize one there: host persistence errors remain
|
|
103
|
+
// authoritative and diagnosable instead of creating a false durable ref.
|
|
104
|
+
const attachmentCompatCtx = attachmentContextForContract(settingsCtx, logging.logger, {
|
|
105
|
+
installAndroidAttachmentCompat,
|
|
106
|
+
})
|
|
107
|
+
// Final structured-flow guard sits closest to core.apply so it sees the
|
|
108
|
+
// actual tool registrations and pre-step listener. It makes bootstrap
|
|
109
|
+
// one-shot, enforces fast/standard/deep quotas, tracks mixed branches,
|
|
110
|
+
// rejects empty/non-evidence results, and applies one shared turn deadline.
|
|
111
|
+
const structuredCtx = installStructuredFlowHardening(attachmentCompatCtx, runtimeConfig)
|
|
112
|
+
// DSH rc.7 publishes llm/adapters-updated synchronously from inside
|
|
113
|
+
// registerAdapter(). Coalesce only Vision Router's listener: nested events
|
|
114
|
+
// mark the topology dirty and the outer pass reruns to a fixed point, so we
|
|
115
|
+
// neither double-register a twin nor lose a provider added mid-pass.
|
|
116
|
+
const reconciledCtx = contextWithCoalescedAdapterUpdates(structuredCtx)
|
|
117
|
+
// index.js historically passes image bytes as `options.input` to the async
|
|
118
|
+
// execFile API. That option is not fed into child stdin, so Tesseract waits
|
|
119
|
+
// for data until the OCR slice expires. Materialize only this exact
|
|
120
|
+
// Tesseract-stdin call to a temporary image file; all other execFile calls
|
|
121
|
+
// keep their native behavior.
|
|
122
|
+
installTesseractExecFileCompat(reconciledCtx)
|
|
123
|
+
|
|
66
124
|
// 启动诊断摘要只描述 composition/apply 的基础配置。设置服务可能稍后
|
|
67
125
|
// 覆盖这些值;每个图片轮还会记录 current() 的实时决策,避免把这个
|
|
68
126
|
// 启动快照误当成最终设置状态。
|
|
@@ -71,7 +129,8 @@ export function apply(ctx, config = {}) {
|
|
|
71
129
|
const local = c.localOllama && typeof c.localOllama === 'object' ? c.localOllama : {}
|
|
72
130
|
const lms = c.localLmStudio && typeof c.localLmStudio === 'object' ? c.localLmStudio : {}
|
|
73
131
|
logging.logger.info(
|
|
74
|
-
'vision-router: base config summary — instantDescribe=%s localDescribeStyle=%s localOllama=%s localLmStudio=%s',
|
|
132
|
+
'vision-router: base config summary — contract=%s instantDescribe=%s localDescribeStyle=%s localOllama=%s localLmStudio=%s',
|
|
133
|
+
rc7 ? 'rc7' : 'rc6',
|
|
75
134
|
c.instantDescribe === true ? 'on' : 'off',
|
|
76
135
|
c.localDescribeStyle === 'structured' ? 'structured' : 'plain',
|
|
77
136
|
local.enabled === true ? 'on' : 'off',
|
|
@@ -81,16 +140,12 @@ export function apply(ctx, config = {}) {
|
|
|
81
140
|
/* diagnostics must never break apply */
|
|
82
141
|
}
|
|
83
142
|
try {
|
|
84
|
-
const
|
|
85
|
-
...bootConfig,
|
|
86
|
-
progressiveTools: hardenedConfig.progressiveTools === true,
|
|
87
|
-
}
|
|
88
|
-
const result = core.apply(attachmentCompatCtx, runtimeConfig)
|
|
143
|
+
const result = core.apply(reconciledCtx, runtimeConfig)
|
|
89
144
|
// DSH rc.7's Settings -> Models surface is backed by the configurable
|
|
90
145
|
// provider directory, not by the live adapter registry alone. Publish the
|
|
91
146
|
// main DeepSeek + 自动识图 route as a derived alias of official DeepSeek so
|
|
92
147
|
// a reinstall restores the expected model-group row without making an
|
|
93
|
-
// arbitrary textProvider look like DeepSeek.
|
|
148
|
+
// arbitrary textProvider look like DeepSeek. On rc.6 the helper is inert.
|
|
94
149
|
installWrapperDirectoryAlias(attachmentCompatCtx, runtimeConfig, logging.logger)
|
|
95
150
|
if (result && typeof result.then === 'function') {
|
|
96
151
|
return result.catch((error) => {
|