概览
dsh-pylon-trae
README / ZH
插件文档
目录摘要
dsh.pub 核对固定版本的组合包契约、运行时事实与分发语义;完整 README 请查看源仓库。
在 GitHub 阅读完整 READMELIMITATIONS
已知限制
**① 卡片这条通道依赖宿主的两件事,任一件变了卡片就整片 403。** 卡片的数据走宿主 web server 上本插件自己注册的路由(`/plugins/dsh-pylon-trae` 与 `/api/plugins/dsh-pylon-trae`), 而请求要过宿主自己的栅栏 `connection.requestRejection`。桌面 app 的 UI 层只转发 `/api/*`, 并且会把 Host 改写成宿主端口、Origin 仍是 app 端口 —— 于是同一个栅栏**对回环请求也回 403**。 我们的处理是**容忍这一种 403**(Host 与 Origin **都是回环**,端口可不同):仅此情形放行并 trace 一次; **401 绝不放行**,非回环 Host/Origin 仍然 403。 ⇒ 若某天宿主改了这套判据,症状是卡片五个区块**全是** `HTTP 403 … 没有返回 JSON(这条路没被转发到插件)`。**先看 `$DSH_HOME\.dsh-pylon-trae\boot.log` 里有没有这行**: ``` host route: fence 403 tolerated as a loopback port hop (host=… origin=…) — the card is served through the desktop app's proxy ``` 有 ⇒ 栅栏已放行,问题在别处;没有 ⇒ 请求在栅栏处就被判掉了(`handleApi` 一次都没被调用)。 另一种"没数据"是插件根本没被 import:模块顶层会打 `[dsh-pylon-trae] module loaded`, **没有这行 = 没被 import;有这行但没有 `apply:` 行 = import 了但 apply 没跑**(inject 依赖没到,插件停在 PENDING)。 **② 图片输入是刻意没开的,不是漏了。** `src/protocol.ts` 顶部有 `NOT IMPLEMENTED — image input (deliberate)` 一节:请求侧**不翻译** `image_url` 内容块,所以目录里 `multimodal === true` 的模型也**不**往 provider 条目的 `input` 里写 `'image'` (恒为 `['text']`)。理由是"先宣告、再让用户的图片静默消失"比不支持更糟。 **③ 单次「测试启用模型」最多 10 个,而且每个都是真请求。** `/models/test` 的 `MAX_PROBE_MODELS = 10`(`src/api.ts`):显式给 `modelIds` 时,去重、丢掉未知 id 之后 最多真的测 10 个,被截掉的用 `requested / tested / truncated` 明说;不给 `modelIds` 只测前 5 个。 每个 verdict 都是**一次真的发往 Trae 的请求**(30s 超时、串行),所以**这一步会花一点点额度**。 反过来,`/models/reload` 与 `/models/refresh` 只拉目录,不发消息、不花额度(`refresh` 会写配置)。 **④ 只在 Windows + Trae CN 上实测过。** 路径与 edition 表按三平台(win32/darwin/linux)写好,但 macOS / Linux **没有真机验证**; 国际版(`ai` 区域)同理 —— 本机没有国际版凭据,代码结构保留了 `cn/ai` 双桶,等有账号时再验。 **⑤ 手打一个内部组件的 id,仍然会被转发出去 —— 刻意如此。** 回环 `GET /v1/models` 只公布对话模型,但 `POST /v1/chat/completions` 解析 `model` 用的是**全目录**: 用户自己往模型页里手打一个 internal id(如 `title_generation`),请求会按它的真名转发到 Trae。 理由写在 `src/shim.ts` 里(`handleChat` 上方):用户手打的 id 可能是网关还没列出来的新模型, "按真名转发、让 Trae 自己回答"比我们替他拒绝更诚实。这是**刻意保留**的,不是过滤漏了一处。 **⑥ `/v1/models` 不按 id 去重,而写进 provider 条目的那一份会去重。** `src/seed.ts` 的 `buildProviderProfile` 用 `seen` 集合按 id 去重;`src/shim.ts` 只是把 `advertisedModels()` 原样映射成 OpenAI list。**当前目录已经按 id 去重**(`fetchDirectoryModels` 用 `byId` Map 归并同一个 `config_name` 的多个 function 行),所以这两个面没有分歧; 若将来网关真的给出重复 id,分歧会先在 `tools/test-api.ts` [9] 节的一致性断言 (`/v1/models` 的 id 集合 == provider 条目的 id 集合)上变红,而不是静默地一边多、一边少。
