Files
deepseek-harness/packages/e2b/lsp-e2b

@deepseek-ai/dsh-lsp-e2b

English | 中文

Generic E2B language-server backend for ctx.lsp. It runs configured stdio servers and reads their source documents inside the shared ctx.e2b sandbox; the provider registry, normalized query results, queues, and protocol connection state remain on the host.

Plugin and configuration

The lsp-e2b plugin injects e2b, lsp, and the concrete dsh-subprocess-e2b service. servers is a non-empty provider-id table:

Server key Default Meaning
command required Remote executable, absolute or resolved on the sandbox PATH at load.
args [] Remote server arguments.
env {} Explicit environment entries passed through the subprocess adapter.
extensionToLanguage required Lowercase leading-dot extension to LSP language id.
initializationOptions / configuration null / null Static initialize options and workspace/configuration answer.
maxMessageBytes 16000000 Largest LSP message accepted from the server.
maxStderrBytes 1000000 Retained raw server stderr tail.
maxDocumentBytes 4000000 Largest remote source opened for one query.
shutdownTimeoutMs 5000 Graceful protocol-shutdown budget.
killGraceMs 2000 Request-cancel and TERM-to-KILL grace.

Provider ids and commands are non-empty; numeric bounds are positive safe integers, and timer values cannot exceed Node's maximum timer delay. Setup uploads one owner-private proxy under ctx.e2b.runtimeRoot, resolves Node and every configured server executable remotely, then registers all providers atomically.

Remote protocol and filesystem

E2B command callbacks are text, while LSP is byte-framed. The installed proxy therefore base64-frames raw server stdout, stderr, and stdin as newline-delimited ASCII JSON; the host validates and decodes every frame before handing bytes to the shared LspInstance protocol engine. initialize.processId is null because host and server do not share a process namespace.

One language-server process is pooled per provider and canonical remote workspace. Queries serialize per workspace but different workspaces run concurrently. Each query canonicalizes the remote workspace and source with realpath, rejects paths outside that workspace, requires a regular file, enforces the size bound before and after reading, decodes strict UTF-8, and uses the ordinary transient didOpen / request / didClose lifecycle. A transport failure disposes the instance and retries the read-only query once on a fresh remote process.

The subprocess adapter owns process groups and escalation, so cancellation and disposal await remote server quiescence. The host owns LSP request ids, pending requests, provider queues, and normalized results.

Model Experience

Indirectly, through @deepseek-ai/dsh-tool-lsp, which exposes normalized semantic navigation and hover results without changing its model-facing schema.

KV Cache effect

No direct invalidation; dsh-tool-lsp owns request-prefix changes.

Known Limitations and Deferred Work

  • Configured servers only — this package does not install language servers, select presets, or synchronize a host workspace into E2B.
  • Host protocol state is not reconnectable — retaining a sandbox does not restore provider queues, JSON-RPC requests, subprocess handles, or document lifecycle state.
  • SDK output retention remains — ASCII framing preserves protocol bytes, but E2B and the subprocess adapter still retain callback output in host memory.
  • Sandbox policy is template-owned — this provider adds no volume, snapshot, credential, or network-policy layer.