Files
deepseek-harness/packages/host/apiproxy
_Kerman 923535fa7a feat(gui): goal wire domain, client goal state, and docked goal bar
- apiproxy goals RPC domain (get/create/edit/pause/resume/complete/clear)
  with CAS refs, zod schemas, and fetch client/handler wiring
- client runtime session goal state: live goal/change meta triggers a
  coalesced refetch; mutations fold transport errors into RpcResult
- web GoalBar: docked strip above the composer (sparkle, phase label,
  truncated objective, inline edit, clear; resume when paused); creation
  stays on the /goal command
- GoalBarActions in the ui-conversation contract layer; IconSparkle16
  moves to ui-primitives icons
2026-07-22 21:30:30 +08:00
..

@deepseek-ai/dsh-host-apiproxy

The ApiProxy front layer every client shape shares: the TS contract (src/api/, zero Node dependencies, importable from the browser) and the fetch carrier pair (src/fetch/: toFetchHandler on the host side, AbstractApiClient plus platform subclasses on the client side). Host assembly lives in dsh-host-runtime.

Contract layer (/api)

Wire messages form a four-quadrant discriminated union — who initiates × request/response — decoupled from the physical channel: ClientRequest (POST /api/<method> body), ServerResponse (that POST's response body), ServerRequest (SSE frame), ClientResponse (POST /api/respond body). Responses always echo the matching request's rpcId and never mint a new one. Method parameter/return structures live only in the domain interface signatures (SessionsApi, HostApi, EventsApi); RpcMethodMap registers the methods and every other position derives via RequestPayload<K>/ResponseValue<K>. Zod schemas anchor satisfies z.ZodType<Wire<T>> and parse at two levels: envelope first, business payload second, dispatched per method. Business errors ride RpcResult's error branch (RpcErrorDetailsMap closes the code set); HTTP status expresses only the carrier.

The layering/protocol decisions are recorded in the GUI layering and RPC protocol RFC; the browser-side consumption architecture in the web client architecture RFC.

Carrier layer (/client + root)

AbstractApiClient holds every protocol invariant — rpcId minting, envelope wrap/unwrap, zod parsing, SSE frame decoding, unary timeout, microtask-batched envelope observation (subscribeEnvelopes) — while platform subclasses supply only the doFetch transport aspect. InProcessApiClient over toFetchHandler(api) is the isomorphic point: the full wire serialization/validation path with no network, used by dsh -p headless.

Model Experience

None, as the package defines the client↔host wire contract and carriers; nothing here reaches a model request.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

  • respond routing is shipped, but pending-interaction state is host-side work — the wire shape (POST /api/respond, RpcReceipt) is final; the pending table that makes late/duplicate answers meaningful lives in dsh-host-runtime and is still a stub there.
  • Reserved seams stay out of RpcMethodMapsession.fork, prompt.mode: 'inject', task.list, host.listModels, and a describe hostInstanceId are documented reservations; an unknown method fails loud at envelope parse rather than getting a not-implemented code.
  • No protocol version field — client and host ship together; host.describe gains a version negotiation field only when an independently released client exists.