Files
deepseek-harness/packages/client/connection/README.zh.md
Yichen Jiang 7dcefeda50 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-8-authoring
# Conflicts:
#	apps/cli/tests/web-agent-presets.e2e.ts
#	packages/client/connection/README.i18n.yaml
#	packages/client/connection/README.md
#	packages/client/connection/README.zh.md
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-primitives/tests/icons.spec.tsx
#	packages/client/ui-settings/src/client/contract/slots.ts
#	packages/host/apiproxy/tests/api-proxy-agent-preset.spec.ts
2026-08-09 23:02:37 +08:00

5.1 KiB
Raw Blame History

@deepseek-ai/dsh-client-connection

English | 中文

协议消费层:客户端插件的 apply 会挂载 ctx.connection(共享 API 客户端 + 当前页面的 loopback 状态 + 单消费方流循环启动器);导出表层携带协议约定类型、AbstractApiClient 抽象,以及循环的 sink配置类型。浏览器载体以 HTTP POST 发送 unaryrespond并为 events.muxevents.host 各开一条只下行的 WebSocket进程内载体满足同一双流抽象。Host half 持有唯一 /api route 及其 Fetch bridge已注册的 TypeRT interceptor 会先认领自己的 Remote endpoint未认领请求再回退 API Proxy。Loopback hostname 判定逻辑留在包内部:/api Host fence 与 WebSocket upgrade 会直接使用它,其他客户端插件则消费派生的 ctx.connection.isLoopback 状态。node 半侧的 /api 路由让特权方法集(host.pickDirectoryhost.openPath,以及整个配置面——settings.describe/openDocument/update/replace/mutatecredentials.describe/set/unset;读取与原生操作也在内,因为 describe 会返回已暴露的配置、打开操作会作用于 Host 桌面,而探测任意引用会报出某条凭据来自何处——以及 agent preset 的创作面 agentPreset.read/copy/openDocument/remove,因为组装指明了一个会话所运行的插件,读取它是侦察,而 copy/remove/openDocument 管理名单并驱动宿主桌面(创作只有复制一种写入,因此这些方法都不接收组装文本或路径);agentPreset.listagentPreset.select 不在其中——名单只携带 id 与信任级别,而选择一个 preset 并不比 session.create 自带的 agentPreset 多给任何能力,何况默认 preset 本就带着 bash以空信任表过信任 fence从而钉在回环——已声明的 trustedHosts 授权可达其余全部方法,而这些方法在真正的认证层出现之前仍只限回环本机。平台载体与 ConnectionController 循环属于包内部apply 负责选择并驱动它们。下行边界见 WebSocket 下行载体 Agent Note

/api 浏览器信任栅栏

node 半侧在桥接或 upgrade 前守卫 /api 下的每个入口(src/api-request-trust.ts)。每个请求——无论是否带浏览器标记——Host 都必须是回环地址权威,或与某个 trustedHosts 条目匹配:带端口的 host:port 条目精确匹配,不带端口的条目匹配任意端口,两侧均经 WHATWG 归一化后比较DNS rebinding 防御)。刻意不为无浏览器标记的 HTTP 请求开捷径:明文 HTTP 下浏览器的图片与导航读取既不带 Origin 也不带 Fetch-Metadata因此无标记请求仍可能是被重绑页面发起的、响应可被读走的读取而 Host 是重绑唯一伪造不了的请求头WebSocket 浏览器握手会带 Origin 并通过同一道比较。非浏览器客户端经由回环地址、CLI 推导的 LAN IP 字面量或已声明的权威通过同一道栅栏。当标记存在时,Origin 必须与 Host 权威完全一致;显式的 sec-fetch-site: cross-site 标记一律拒绝。不是纯的、规范形 host[:port] 权威的 trustedHosts 条目——即 WHATWG 解析读回后与原文不完全一致的——会让插件加载明确报错:否则解析会悄悄授权 harness.internal/path 这类笔误里的 hostname或把悬空冒号、补零端口放大成任意端口授权。HTTP 失败在任何 RPC 分发之前以纯 403 应答upgrade 失败在启动任何 event stream 前拒绝握手。因此非回环(--host 0.0.0.0部署需要让自己的服务权威被信任dsh CLI 会自行推导本机的 LAN IP 字面量,其 --trusted-host flag 用于声明具名权威,所以 cordis.yml 中的 trustedHosts 面向 CLI 不参与引导的组合。这道栅栏是可达性策略而不是认证Web 载体不提供认证层。决策记录:api 浏览器信任边界 Agent Note

/api WebSocket 下行

/api/events.mux/api/events.host 各接受一条 WebSocket upgrade并只向浏览器发送对应的 ServerRequest text message客户端不会在这些 socket 上发送业务数据。任一 socket 结束都会使当前 connection generation 失败并重建两条流,连接就绪仍要求两条 socket open 且 host.describe HTTP 调用成功。Host teardown 会终止两条 socket、中止各自的 source并等待 source 清理完成后再返回。普通网络 GET 这些路径会返回 426不保留 SSE 回退;toFetchHandler 的 SSE 编解码只服务进程内同构载体。

模型体验

无。协议消费层只在浏览器与主机之间搬运已经组合好的消息;这里没有任何内容进入模型请求。

KV Cache 影响

无;该包既不组装也不发送提供方请求。

已知限制与暂缓事项

  • History 会恢复未附加的会话:打开 history 可能创建宿主侧 agent并增加首次打开的延迟没有仅从持久化读取的路径。