@deepseek-ai/dsh-client-connection 0.1.0-rc.8 → 0.1.1-rc.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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/connection/README.md
5
- README.md: f0a707cc5f3a962c7852f7323c727d0a39a57b10
6
- README.zh.md: b529eebf9af93e36b6b92c19964678b7f5a04ea1
5
+ README.md: 71ef204a589bb67c15ccab58d3cac5a13782ce27
6
+ README.zh.md: 6d33ac3c13cdfceeba6e7472b618084267d09bbc
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [中文](README.zh.md)
4
4
 
5
- Wire consumer layer: the client plugin's apply mounts `ctx.connection` (shared api client + current-page loopback state + observable generation-scoped `hostDescription` + single-consumer stream-loop starter); the export face carries the wire contract types, the `AbstractApiClient` abstraction, and the loop's sink/config types. Each successful readiness handshake publishes the exact `host.describe` value before `onConnected`; generation loss and explicit stop clear it, so native-capability consumers never retain a disconnected answer. The browser carrier uses HTTP POST for unary and respond operations and opens one downlink-only WebSocket each for `events.mux` and `events.host`; the in-process carrier satisfies the same two-stream abstraction. The Host half owns the single `/api` route and its Fetch bridge; a registered Typert interceptor claims its Remote endpoints before the API Proxy fallback. Loopback hostname classification stays package-internal: the `/api` Host fence and WebSocket upgrades use it directly, while other client plugins consume the derived `ctx.connection.isLoopback` state. The node half's `/api` route pins the privileged method set (`host.pickDirectory`, `host.openPath`, and the whole configuration plane — `settings.describe`/`openDocument`/`update`/`replace`/`mutate` and `credentials.describe`/`set`/`unset`; reads and native actions included, since describing returns the exposed configuration, opening acts on the Host desktop, and probing an arbitrary reference reports where a credential comes from — and the agent-preset authoring plane, `agentPreset.read`/`copy`/`openDocument`/`remove`, since a composition names the plugins a session runs, so reading one is reconnaissance, and copy/remove/openDocument manage the roster and drive the host desktop (authoring is copy-only, so none of them accepts composition text or a path); `agentPreset.list` and `agentPreset.select` stay out — the roster carries only ids and trust, and choosing a preset grants nothing `session.create`'s own `agentPreset` did not, over a default that already carries bash) to loopback by passing the trust fence with an empty trust list — a declared `trustedHosts` authority reaches every other method, while these stay loopback-local until a real authentication layer exists. The platform carriers and ConnectionController loop are package-internal; apply selects and drives them. The downlink boundary is documented in the [WebSocket downlink carrier Agent Note](../../../.agents/notes/implemented/architecture/2026-08-04-websocket-downlink-carrier.md).
5
+ Wire consumer layer: the client plugin's apply mounts `ctx.connection` (shared api client + current-page loopback state + observable generation-scoped `hostDescription` + single-consumer stream-loop starter); the export face carries the wire contract types, the `AbstractApiClient` abstraction, and the loop's sink/config types. Each successful readiness handshake publishes the exact `host.describe` value before `onConnected`; generation loss and explicit stop clear it, so native-capability consumers never retain a disconnected answer. The browser carrier uses HTTP POST for unary and respond operations and opens one downlink-only WebSocket each for `events.mux` and `events.host`; the in-process carrier satisfies the same two-stream abstraction. The exported `ClientTransportHooks` names the page global `__DSH_TRANSPORT__` that replaces the browser carrier wholesale: the served web app leaves it unset and gets HTTP + WebSocket, while a shell owning a different physical transport (the worker preview's postMessage tunnel) provides `createApiClient` and `fetch` — plus `loadBundle` when it also owns bundle bytes — instead of forking the plugin. The Host half owns the single `/api` route and its Fetch bridge; a registered Typert interceptor claims its Remote endpoints before the API Proxy fallback. Loopback hostname classification stays package-internal: the `/api` Host fence and WebSocket upgrades use it directly, while other client plugins consume the derived `ctx.connection.isLoopback` state. The node half's `/api` route pins the privileged method set (`host.pickDirectory`, `host.openPath`, and the whole configuration plane — `settings.describe`/`openDocument`/`update`/`replace`/`mutate` and `credentials.describe`/`set`/`unset`; reads and native actions included, since describing returns the exposed configuration, opening acts on the Host desktop, and probing an arbitrary reference reports where a credential comes from — and the agent-preset authoring plane, `agentPreset.read`/`copy`/`openDocument`/`remove`, since a composition names the plugins a session runs, so reading one is reconnaissance, and copy/remove/openDocument manage the roster and drive the host desktop (authoring is copy-only, so none of them accepts composition text or a path); `agentPreset.list` and `agentPreset.select` stay out — the roster carries only ids and trust, and choosing a preset grants nothing `session.create`'s own `agentPreset` did not, over a default that already carries bash) to loopback by passing the trust fence with an empty trust list — a declared `trustedHosts` authority reaches every other method, while these stay loopback-local until a real authentication layer exists. The platform carriers and ConnectionController loop are package-internal; apply selects and drives them. The downlink boundary is documented in the [WebSocket downlink carrier Agent Note](../../../.agents/notes/implemented/architecture/2026-08-04-websocket-downlink-carrier.md).
6
6
 
7
7
  ## /api browser-trust fence
8
8
 
@@ -23,4 +23,4 @@ None; this package neither assembles nor sends a provider request.
23
23
  ## Known Limitations and Deferred Work
24
24
 
25
25
  - **History resumes an unattached session** — opening history may create the host-side agent and add latency to the first open; there is no persistence-only read path.
26
- - **The `/api` bridge buffers each request body in memory** — `maxRequestBodyBytes` (default 160 MiB, sized for the default 100 MiB aggregate image limit after base64 expansion plus envelope headroom) is therefore also the per-request resident bound; a streaming body path would be needed to lower it without shrinking the image limits.
26
+ - **The `/api` bridge buffers each request body in memory** — `maxRequestBodyBytes` (default 300 MiB, sized for the default 200 MiB aggregate image limit after base64 expansion plus envelope headroom) is therefore also the per-request resident bound; a streaming body path would be needed to lower it without shrinking the image limits.
package/README.zh.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  [English](README.md) | 中文
4
4
 
5
- 协议消费层:客户端插件的 apply 会挂载 `ctx.connection`(共享 API 客户端 + 当前页面的 loopback 状态 + 可观察且按 generation 生效的 `hostDescription` + 单消费方流循环启动器);导出表层携带协议约定类型、`AbstractApiClient` 抽象,以及循环的 sink/配置类型。每次就绪握手成功后,都会在 `onConnected` 之前发布完整的 `host.describe` 值;generation 失效或显式 stop 会清空它,因此原生能力消费者不会保留已经断线的判断。浏览器载体以 HTTP POST 发送 unary/respond,并为 `events.mux` 与 `events.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.pickDirectory`、`host.openPath`,以及整个配置面——`settings.describe`/`openDocument`/`update`/`replace`/`mutate` 与 `credentials.describe`/`set`/`unset`;读取与原生操作也在内,因为 describe 会返回已暴露的配置、打开操作会作用于 Host 桌面,而探测任意引用会报出某条凭据来自何处——以及 agent(智能体) preset 的创作面 `agentPreset.read`/`copy`/`openDocument`/`remove`,因为组装指明了一个会话所运行的插件,读取它是侦察,而 copy/remove/openDocument 管理名单并驱动宿主桌面(创作只有复制一种写入,因此这些方法都不接收组装文本或路径);`agentPreset.list` 与 `agentPreset.select` 不在其中——名单只携带 id 与信任级别,而选择一个 preset 并不比 `session.create` 自带的 `agentPreset` 多给任何能力,何况默认 preset 本就带着 bash)以空信任表过信任 fence,从而钉在回环——已声明的 `trustedHosts` 授权可达其余全部方法,而这些方法在真正的认证层出现之前仍只限回环本机。平台载体与 ConnectionController 循环属于包内部;apply 负责选择并驱动它们。下行边界见 [WebSocket 下行载体 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-04-websocket-downlink-carrier.md)。
5
+ 协议消费层:客户端插件的 apply 会挂载 `ctx.connection`(共享 API 客户端 + 当前页面的 loopback 状态 + 可观察且按 generation 生效的 `hostDescription` + 单消费方流循环启动器);导出表层携带协议约定类型、`AbstractApiClient` 抽象,以及循环的 sink/配置类型。每次就绪握手成功后,都会在 `onConnected` 之前发布完整的 `host.describe` 值;generation 失效或显式 stop 会清空它,因此原生能力消费者不会保留已经断线的判断。浏览器载体以 HTTP POST 发送 unary/respond,并为 `events.mux` 与 `events.host` 各开一条只下行的 WebSocket;进程内载体满足同一双流抽象。导出的 `ClientTransportHooks` 命名了整体替换浏览器载体的页面全局量 `__DSH_TRANSPORT__`:served web app 不设置它、走 HTTP + WebSocket;拥有另一种物理传输的壳(worker 预览的 postMessage 隧道)则在此提供 `createApiClient` 与 `fetch`——当它同时持有 bundle 字节时再加 `loadBundle`——而不必 fork 本插件。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.pickDirectory`、`host.openPath`,以及整个配置面——`settings.describe`/`openDocument`/`update`/`replace`/`mutate` 与 `credentials.describe`/`set`/`unset`;读取与原生操作也在内,因为 describe 会返回已暴露的配置、打开操作会作用于 Host 桌面,而探测任意引用会报出某条凭据来自何处——以及 agent(智能体) preset 的创作面 `agentPreset.read`/`copy`/`openDocument`/`remove`,因为组装指明了一个会话所运行的插件,读取它是侦察,而 copy/remove/openDocument 管理名单并驱动宿主桌面(创作只有复制一种写入,因此这些方法都不接收组装文本或路径);`agentPreset.list` 与 `agentPreset.select` 不在其中——名单只携带 id 与信任级别,而选择一个 preset 并不比 `session.create` 自带的 `agentPreset` 多给任何能力,何况默认 preset 本就带着 bash)以空信任表过信任 fence,从而钉在回环——已声明的 `trustedHosts` 授权可达其余全部方法,而这些方法在真正的认证层出现之前仍只限回环本机。平台载体与 ConnectionController 循环属于包内部;apply 负责选择并驱动它们。下行边界见 [WebSocket 下行载体 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-04-websocket-downlink-carrier.zh.md)。
6
6
 
7
7
  ## /api 浏览器信任栅栏
8
8
 
9
- node 半侧在桥接或 upgrade 前守卫 `/api` 下的每个入口(`src/api-request-trust.ts`)。每个请求——无论是否带浏览器标记——`Host` 都必须是回环地址权威,或与某个 `trustedHosts` 条目匹配:带端口的 `host:port` 条目精确匹配,不带端口的条目匹配任意端口,两侧均经 WHATWG 归一化后比较(DNS rebinding 防御)。刻意不为无浏览器标记的 HTTP 请求开捷径:明文 HTTP 下浏览器的图片与导航读取既不带 `Origin` 也不带 Fetch-Metadata,因此无标记请求仍可能是被重绑页面发起的、响应可被读走的读取,而 Host 是重绑唯一伪造不了的请求头;WebSocket 浏览器握手会带 `Origin` 并通过同一道比较。非浏览器客户端经由回环地址、部署推导的 LAN IP 字面量或已声明的权威通过同一道栅栏。当标记存在时,如附带 `Origin`,则它必须与 Host 权威完全一致;显式的 `sec-fetch-site: cross-site` 标记一律拒绝。不是纯的、规范形 `host[:port]` 权威的 `trustedHosts` 条目——即 WHATWG 解析读回后与原文不完全一致的——会让插件加载明确报错:否则解析会悄悄授权 `harness.internal/path` 这类笔误里的 hostname,或把悬空冒号、补零端口放大成任意端口授权。HTTP 失败在任何 RPC 分发之前以纯 403 应答,upgrade 失败在启动任何事件流前拒绝握手。非回环组合必须显式信任其服务权威:Web 运行时从全接口服务器配置推导 LAN IP 字面量,cordis.yml 中的 `trustedHosts` 与 CLI(命令行界面)的 `--trusted-host` flag 则声明具名权威。`dsh web --host 0.0.0.0` 在远程访问具备认证层之前有意不受支持。这道栅栏是可达性策略,而不是认证;Web 载体不提供认证层。决策记录:[api 浏览器信任边界 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.md)。
9
+ node 半侧在桥接或 upgrade 前守卫 `/api` 下的每个入口(`src/api-request-trust.ts`)。每个请求——无论是否带浏览器标记——`Host` 都必须是回环地址权威,或与某个 `trustedHosts` 条目匹配:带端口的 `host:port` 条目精确匹配,不带端口的条目匹配任意端口,两侧均经 WHATWG 归一化后比较(DNS rebinding 防御)。刻意不为无浏览器标记的 HTTP 请求开捷径:明文 HTTP 下浏览器的图片与导航读取既不带 `Origin` 也不带 Fetch-Metadata,因此无标记请求仍可能是被重绑页面发起的、响应可被读走的读取,而 Host 是重绑唯一伪造不了的请求头;WebSocket 浏览器握手会带 `Origin` 并通过同一道比较。非浏览器客户端经由回环地址、部署推导的 LAN IP 字面量或已声明的权威通过同一道栅栏。当标记存在时,如附带 `Origin`,则它必须与 Host 权威完全一致;显式的 `sec-fetch-site: cross-site` 标记一律拒绝。不是纯的、规范形 `host[:port]` 权威的 `trustedHosts` 条目——即 WHATWG 解析读回后与原文不完全一致的——会让插件加载明确报错:否则解析会悄悄授权 `harness.internal/path` 这类笔误里的 hostname,或把悬空冒号、补零端口放大成任意端口授权。HTTP 失败在任何 RPC 分发之前以纯 403 应答,upgrade 失败在启动任何事件流前拒绝握手。非回环组合必须显式信任其服务权威:Web 运行时从全接口服务器配置推导 LAN IP 字面量,cordis.yml 中的 `trustedHosts` 与 CLI(命令行界面)的 `--trusted-host` flag 则声明具名权威。`dsh web --host 0.0.0.0` 在远程访问具备认证层之前有意不受支持。这道栅栏是可达性策略,而不是认证;Web 载体不提供认证层。决策记录:[api 浏览器信任边界 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-28-api-browser-trust-boundary.zh.md)。
10
10
 
11
11
  ## `/api` WebSocket 下行
12
12
 
@@ -23,4 +23,4 @@ node 半侧在桥接或 upgrade 前守卫 `/api` 下的每个入口(`src/api-r
23
23
  ## 已知限制与暂缓事项
24
24
 
25
25
  - **History 会恢复未附加的会话**:打开 history 可能创建宿主侧 agent,并增加首次打开的延迟;没有仅从持久化读取的路径。
26
- - **`/api` 桥把每个请求体整体缓冲在内存里**:`maxRequestBodyBytes`(默认 160 MiB,按默认 100 MiB 图片总量上限经 base64 膨胀加信封余量得出)因此同时是单请求的驻留内存上界;要降低它而不缩小图片限额,需要流式请求体路径。
26
+ - **`/api` 桥把每个请求体整体缓冲在内存里**:`maxRequestBodyBytes`(默认 300 MiB,按默认 200 MiB 图片总量上限经 base64 膨胀加信封余量得出)因此同时是单请求的驻留内存上界;要降低它而不缩小图片限额,需要流式请求体路径。
package/lib/client.js CHANGED
@@ -10200,9 +10200,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10200
10200
  const ENDPOINT_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/;
10201
10201
  /**
10202
10202
  * Create the browser-backed generic RPC caller.
10203
+ * @param doFetch - transport override; defaults to the page's global fetch.
10203
10204
  * @returns caller that owns request correlation and response-envelope validation.
10204
10205
  */
10205
- function createWebConnectionRpc() {
10206
+ function createWebConnectionRpc(doFetch) {
10207
+ const send = doFetch ?? ((input, init) => globalThis.fetch(input, init));
10206
10208
  return { async call(channel, endpoint, payload, signal) {
10207
10209
  assertTarget(channel, endpoint);
10208
10210
  const rpcId = RpcId(randomUuid());
@@ -10212,7 +10214,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10212
10214
  method: endpoint,
10213
10215
  payload
10214
10216
  };
10215
- const response = await globalThis.fetch(new URL(`${channel}/${endpoint}`, resolveBase()), {
10217
+ const response = await send(new URL(`${channel}/${endpoint}`, resolveBase()), {
10216
10218
  method: "POST",
10217
10219
  headers: { "content-type": "application/json" },
10218
10220
  body: JSON.stringify(message),
@@ -10260,8 +10262,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
10260
10262
  function apply(ctx) {
10261
10263
  const pageLocation = typeof location === "undefined" ? void 0 : location;
10262
10264
  const fixtureClient = pageLocation !== void 0 && new URLSearchParams(pageLocation.search).has("fixture") ? new FixtureApiClient() : void 0;
10263
- const api = fixtureClient ?? new WebApiClient();
10264
- const rpc = fixtureClient?.rpc ?? createWebConnectionRpc();
10265
+ const transport = globalThis.__DSH_TRANSPORT__;
10266
+ const api = fixtureClient ?? transport?.createApiClient() ?? new WebApiClient();
10267
+ const rpc = fixtureClient?.rpc ?? createWebConnectionRpc(transport?.fetch);
10265
10268
  let started = false;
10266
10269
  let description;
10267
10270
  const descriptionListeners = /* @__PURE__ */ new Set();
package/lib/index.js CHANGED
@@ -23,10 +23,10 @@ const HOST_EVENTS_PATH = `${API_PATH}/events.host`;
23
23
  * web carrier; the fetch-shaped handler itself is transport-agnostic).
24
24
  */
25
25
  /** Default carrier cap for all HTTP RPC bodies: sized for the default
26
- * aggregate image limit (100 MiB) after base64 expansion plus envelope
27
- * headroom (~134.3 MiB required), rounded up for slack. The bridge buffers
26
+ * aggregate image limit (200 MiB) after base64 expansion plus envelope
27
+ * headroom (~267.7 MiB required), rounded up for slack. The bridge buffers
28
28
  * each body in memory, so this cap is also the per-request resident bound. */
29
- const DEFAULT_MAX_REQUEST_BODY_BYTES = 160 * 1024 * 1024;
29
+ const DEFAULT_MAX_REQUEST_BODY_BYTES = 300 * 1024 * 1024;
30
30
  /**
31
31
  * Bridge one node:http request to the fetch-shaped handler (client close
32
32
  * aborts; SSE bodies stream out chunk by chunk).
@@ -529,7 +529,7 @@ const PRIVILEGED_METHODS = new Set([
529
529
  */
530
530
  function apply(ctx, config) {
531
531
  const trustedHosts = config?.trustedHosts ?? [];
532
- const maxRequestBodyBytes = config?.maxRequestBodyBytes ?? 167772160;
532
+ const maxRequestBodyBytes = config?.maxRequestBodyBytes ?? 314572800;
533
533
  for (const entry of trustedHosts) assertTrustedAuthority(entry);
534
534
  if (ctx.get("apiProxy") !== void 0) assertImageBodyCapacity(ctx, maxRequestBodyBytes);
535
535
  const fetchHandler = new HostConnectionService(ctx, trustedHosts).createSharedFetchHandler(API_PATH, { async fetch(request) {
@@ -6,11 +6,13 @@
6
6
  import type { Context } from '@deepseek-ai/cordis';
7
7
  import type { HostDescription, IApiClient } from './api.ts';
8
8
  import { type ConnectionConfig, type ConnectionSinks, type ConnectionState } from './connection.ts';
9
+ import { type RpcFetch } from './rpc.ts';
9
10
  import type { ClientConnectionRpc } from '../rpc.ts';
10
11
  export type { ApiProxy, SessionsApi, SessionSearchItem, SessionSummary, PromptContentPart, HostApi, EventsApi, MuxFrame, HostFrame, ApprovalResponsePayload, QuestionResponsePayload, HistoryEntry, ToolEventView, DirectoryEntry, DirectoryListing, ToolCallView, ToolResultView, WorkspaceApi, WorkspaceId, WorkspaceView, SkillsApi, SkillEntry, ModelCatalogFailure, ModelCatalogModel, ModelProviderGroup, ModelReasoning, MessageId, ModelReasoningEffort, ModelSelection, QueueAction, QueuedInboxItem, SessionModels, SubagentsApi, SubagentAddress, SubagentCatalog, SubagentListEntry, SubagentPromptReceipt, JobView, RpcRequest, RpcResponse, RpcResult, RpcError, RpcErrorCode, ClientRequest, ServerResponse, ServerRequest, ClientResponse, RpcMessage, RpcReceipt, HostDescription, IApiClient, SessionId, SessionEvent, ContentBlock, StreamChunk, GoalsApi, GoalRef, SettingsApi, SettingsNamespaceView, SettingsPathOpView, SettingsSecretView, CredentialsApi, CredentialView, ConfigurableProviderView, DiscoveredModelView, LlmApi, } from './api.ts';
11
12
  export { RpcId, AbstractApiClient, transportError, } from './api.ts';
12
13
  export type { ConnectionConfig, ConnectionSinks, ConnectionState };
13
14
  export type { ClientConnectionRpc } from '../rpc.ts';
15
+ export type { RpcFetch } from './rpc.ts';
14
16
  /** Observable Host description published by each completed connection handshake. */
15
17
  export interface HostDescriptionSource {
16
18
  /** Latest connected-generation description; absent before connect and while reconnecting. */
@@ -20,6 +22,24 @@ export interface HostDescriptionSource {
20
22
  }
21
23
  /** Required services (none — this is the wire root). */
22
24
  export declare const inject: string[];
25
+ /**
26
+ * Carrier override installed on the page global before plugin boot. The served
27
+ * web app leaves it unset and gets HTTP + WebSocket; a shell that owns a
28
+ * different physical transport (the worker preview's postMessage tunnel)
29
+ * provides both halves here instead of forking this plugin.
30
+ */
31
+ export interface ClientTransportHooks {
32
+ /** Build the API carrier: unary calls plus the two downstream event streams. */
33
+ createApiClient(): IApiClient;
34
+ /** Transport for generic unary RPC channels (the Typert gateway). */
35
+ fetch: RpcFetch;
36
+ /**
37
+ * Bundle transport for the module system, present when the carrier also owns
38
+ * bundle bytes (the worker tunnel). Absent in the served web app, whose
39
+ * bundles load over HTTP.
40
+ */
41
+ loadBundle?(url: string): Promise<void>;
42
+ }
23
43
  /**
24
44
  * The ctx.connection service API: the API client plus a one-shot
25
45
  * controller starter (the runtime plugin supplies sinks when its object layer
@@ -1,8 +1,11 @@
1
1
  /** Browser caller for generic Connection unary RPC channels. */
2
2
  import type { ClientConnectionRpc } from '../rpc.ts';
3
+ /** Transport this caller posts through; same signature as the global `fetch`. */
4
+ export type RpcFetch = (input: URL, init: RequestInit) => Promise<Response>;
3
5
  /**
4
6
  * Create the browser-backed generic RPC caller.
7
+ * @param doFetch - transport override; defaults to the page's global fetch.
5
8
  * @returns caller that owns request correlation and response-envelope validation.
6
9
  */
7
- export declare function createWebConnectionRpc(): ClientConnectionRpc;
10
+ export declare function createWebConnectionRpc(doFetch?: RpcFetch): ClientConnectionRpc;
8
11
  //# sourceMappingURL=rpc.d.ts.map
@@ -4,8 +4,8 @@
4
4
  */
5
5
  import type { IncomingMessage, ServerResponse } from 'node:http';
6
6
  /** Default carrier cap for all HTTP RPC bodies: sized for the default
7
- * aggregate image limit (100 MiB) after base64 expansion plus envelope
8
- * headroom (~134.3 MiB required), rounded up for slack. The bridge buffers
7
+ * aggregate image limit (200 MiB) after base64 expansion plus envelope
8
+ * headroom (~267.7 MiB required), rounded up for slack. The bridge buffers
9
9
  * each body in memory, so this cap is also the per-request resident bound. */
10
10
  export declare const DEFAULT_MAX_REQUEST_BODY_BYTES: number;
11
11
  /** Transport-independent request handler consumed by the Host HTTP bridge. */
@@ -19,7 +19,7 @@ export interface ConnectionConfig {
19
19
  * that is not a bare, canonical authority fails the plugin load.
20
20
  */
21
21
  trustedHosts?: string[];
22
- /** Maximum buffered JSON body for every `/api` request. */
22
+ /** Maximum buffered JSON body for every `/api` request. Default: 300 MiB. */
23
23
  maxRequestBodyBytes?: number;
24
24
  }
25
25
  export declare const Config: z<ConnectionConfig>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-connection",
3
3
  "description": "Wire consumer layer: HTTP-up/WebSocket-down client, ConnectionController dual streams with reconnect, and fixture api",
4
- "version": "0.1.0-rc.8",
4
+ "version": "0.1.1-rc.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -48,26 +48,26 @@
48
48
  "lib/types/**/*.d.ts"
49
49
  ],
50
50
  "peerDependencies": {
51
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.8",
52
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.8",
53
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.8",
54
- "@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.8",
55
- "@deepseek-ai/dsh-commands": "^0.1.0-rc.8",
56
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.8",
57
- "@deepseek-ai/dsh-session": "^0.1.0-rc.8",
58
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.8",
59
- "@deepseek-ai/cordis": "^4.0.1"
51
+ "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
52
+ "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
53
+ "@deepseek-ai/cordis": "^4.0.1",
54
+ "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.2",
55
+ "@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
56
+ "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
57
+ "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
58
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
59
+ "@deepseek-ai/dsh-attachment": "^0.1.1-rc.2"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/ws": "^8.18.1",
63
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.8",
63
+ "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
64
64
  "@deepseek-ai/cordis": "^4.0.1",
65
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.8",
66
- "@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.8",
67
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.8",
68
- "@deepseek-ai/dsh-commands": "^0.1.0-rc.8",
69
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.8",
70
- "@deepseek-ai/dsh-session": "^0.1.0-rc.8",
71
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.8"
65
+ "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
66
+ "@deepseek-ai/dsh-attachment": "^0.1.1-rc.2",
67
+ "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
68
+ "@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
69
+ "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
70
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
71
+ "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.2"
72
72
  }
73
73
  }