Repository navigation
feat: dsh native mode — full plugin via bili plugin install dsh + upgraded launcher (#941) - #942
Conversation
…intercept) via plugin install and launcher (#941) - native-intercept: headersFor hook + attach mode (no rewrite, stamp only) + already-routed /bili/ model URLs get headers without rewriting - dsh-native.ts: cordis plugin (inject tools/commands/agents) — attach (launcher/BILLION_CONTENT_ATTACH) or self-spawn proxy; manifest tools registered verbatim (parameters = JSON schema pass-through); headersFor gates plugin mode on tool readiness (pi.ts discipline); conversation id from ctx.agents.currentInitiator() at request time; /acp session-bound with latest fallback; BILI_NATIVE_DSH=0 opt-out - plugin-install: dsh agent — managed block (# bili begin/end markers) in every ~/.dsh/profiles/*/cordis.patch.yml: bili-native insert + compaction-basic auto:false override; remove restores placeholder []; status counts profiles - launcher: writeDshAcpPatch now carries dsh-native + compaction override (dsh-acp.js kept for old overlays) - tests: dsh-native.test.ts (10), native-intercept headersFor/attach (4), launcher/plugin-agent updated - README bilingual dsh sections
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-942Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr942.tgz
npm install -g packageInstall instructions are refreshed on each push. |
[bot] 🏷 Review of What I checkedCode walkthrough
Local pre-flight (on the PR head)
|
[bot] 🏷 Follow-up — the URL-assertion fix landed ( Root cause — latent Windows race, not introduced by this PRThis PR touches none of
Linux/macOS never hit it because there Fixed directly on the branch (test-only)Commit
Local pre-flight on the new head: full suite 1877 pass / 0 fail / 2 skipped, typecheck clean, build clean. Pushed; CI re-running. If you'd rather keep this PR strictly scoped to dsh, say so and I'll move those two test commits onto their own branch/PR — otherwise they ride along since they're what unblocks windows CI here. 第二轮 CI 暴露的另两个失败是仓库里早已存在的 Windows 竞态(CA 目录隔离在 win32 上失效: |
[bot] 🏷 Final status — CI is fully green on head Recap of what this branch now carries:
Both extra commits are test-only; if you want this PR strictly scoped to dsh, I can split them out — otherwise they're what makes windows CI honest here. One item still open for your call (from my first review note): the shared attach-mode no-rewrite change in Aside from that decision, nothing blocks merging on my side. 最终状态:CI 全绿(含两个 Windows job),PR 可合并。我补了两个纯测试提交——一个修 PR 自身断言的平台相关失败,一个修仓库里早已存在的 Windows CA 目录竞态;唯一待你拍板的是 native-intercept attach 模式不重写 URL 会让 opencode V1 无显式 baseURL 的 provider 静默绕过压缩(建议改成 dsh 专属开关),其余无阻塞。 |
… plugin (#941) cordis validates loader entry ids across ALL merged patch layers and hard-fails boot on duplicates (`duplicate loader entry id: bili-native`, verified against dsh 0.1.1-rc.2). A user who ran `bili plugin install dsh` and then launched via `bili dsh` got two `id: bili-native` inserts (persistent cordis.patch.yml block + launcher --patch overlay) and dsh could not start at all. The launcher now skips its overlay when any profile carries the managed block (dshNativeInstalled in plugin-install.ts) — the persistent block already provides the plugin insert plus the compaction-basic override, so nothing is lost. Fresh users (no install) keep the overlay exactly as before. Verified with real dsh 0.1.1-rc.2: persistent-only boot passes the loader (plugin registers, proxy spawns); persistent+overlay reproduces the crash; overlay-only stays clean. Typecheck + full suite (1878 pass) + build green.
The #941 stamp-only attach branch silently dropped compression for OpenCode 1.x under `bili plugin install opencode` with a preset BILLION_CONTEXT_PROXY/BILLION_CONTEXT_ATTACH and a provider without an explicit baseURL: the V1 `server()` surface shares the module-level intercept state (attach=true), and the V1 fetch patch is exactly what used to route those SDK-default-baseURL requests into the proxy. Attach now rewrites to `${origin}/bili/${url}` exactly like spawn (#809 probe+rewrite semantics restored). For dsh under the `bili dsh` launcher this is doubly safe: settings-overlay URLs are already `/bili/`-shaped and take the routed branch (headers only), and rewriting a raw upstream URL to the loopback proxy is never proxied by the MITM envs (an http loopback target bypasses HTTPS_PROXY/HTTP_PROXY forwarding in every case that matters — worst case an absolute-form self-hop, which the proxy unwraps normally). - native-intercept: attach branch removed (unified rewrite+stamp path); interface docs updated - tests: attach assertions now expect the rewrite; headersFor gating unchanged
|
Review item resolved in Why that is safe for both hosts:
Docs/comments updated to match; attach-mode tests now assert the rewrite. Typecheck + full suite (1878 pass) + build green. |
[bot] 🏷 Verified
Also reviewed the other new commit Pre-flight on No open items left from my side — merge is yours to make. 核对通过:attach 专用分支整体移除后,opencode V1 的 probe+rewrite 语义精确恢复(两个宿主 attach 都不设 respawn,失败即 fail-closed、绝不对外部代理拉起新进程),dsh 侧"回环目标永不被代理 env 拦截"的推理成立,测试与中英文档同步更新;顺带核对了同批的 |
Fixes #941
What
dsh gets full plugin-mode compression in BOTH lanes, sharing one cordis plugin (
src/agent/dsh-native.ts):bili plugin install dsh(new): appends a managed block (# bili begin/# bili endmarkers, user entries/comments preserved, placeholder[]replaced and restored on remove) to every~/.dsh/profiles/*/cordis.patch.yml. At load the plugin self-spawns a proxy (attaches to a healthy instance instead of doubling), patchesglobalThis.fetchto rewrite model-API URLs to<proxy>/bili/<url>, registers the manifest tools (compress/decompress/acp_status) as native dsh tools, and disables dsh auto-compaction (compaction-basic→auto: falseoverride — a patch replaces the row's whole config and dsh-base ships it config-less).bili dsh(upgraded): the--patchoverlay now injects the SAME full plugin (was:/acp-panel-onlydsh-acp.js, kept for old overlays). Under the launcher the plugin ATTACHES to the launcher's proxy — no second spawn, routing stays with the launcher (proxy envs / settings overlay), the fetch patch only stamps headers, including on already-routed/bili/-prefixed requests.Key mechanics (verified against dsh 0.1.1-rc.2 sources)
ctx.tools.registerprojectsdefinition.parametersverbatim onto the model wire (defineTool merely compiles the author spec) — the proxy manifest'sinput_schemaIS a real JSON Schema, so no conversion is needed.ctx.agents.currentInitiator()— dsh's AsyncLocalStorage attribution, read synchronously at request time inside the agent's driver chain (withInitiatorwraps the loop's kick, so LLM fetches run inside the boundary). Tool executes useexec.agent.session.idand fail loudly when agentless.headersForreturns nothing until the manifest registration completes — round 1 rides wire mode instead of arriving tool-less.BILLION_CONTEXT_PLUGIN=0,BILI_NATIVE_DSH=0,BILI_PROVIDER_REWRITES) > attach (BILLION_CONTEXT_ATTACH??BILLION_CONTEXT_PROXY) > spawn — same shape asplanNativeOpencode(opencode 2.x: no-launcher npm-plugin deployment — plugins: ["billion-context"], plugin lazily spawns the proxy #809).native-intercept changes
headersFor?: (url) => Record<string,string>hook; stamped on rewritten (spawn), attach-mode, and already-routed/bili/requests; all three init.headers forms + Request-object inputs handled (withHeaders).routedBiliModelUrl()predicate (embedded model URL from/bili/form).Known limitation
Manual
/compacthas no dsh-side event hook, so its boundary is left to the kernel's natural ingest diff (auto-compaction is off — #395 gap acceptable, noted in README).Pre-flight
npm run typecheck✅npm test— 1878 pass / 0 fail (new: tests/dsh-native.test.ts ×10, native-intercept headersFor/attach ×4; launcher + plugin-agent assertions updated for the new patch content and the 6th agent)npm run build✅ (dist/agent/dsh-native.js, self-contained)