@vidge/dsh-agent-hub 0.1.0-rc1
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/LICENSE +21 -0
- package/README.md +133 -0
- package/README.zh.md +115 -0
- package/cordis.patch.yml +22 -0
- package/lib/client.js +1494 -0
- package/lib/index.js +5045 -0
- package/lib/invariant.js +96 -0
- package/lib/types/client/LoopEngineComposerSelect.d.ts +73 -0
- package/lib/types/client/LoopEngineSection.d.ts +43 -0
- package/lib/types/client/engine-rpc.d.ts +74 -0
- package/lib/types/client/index.d.ts +28 -0
- package/lib/types/client/locales.d.ts +44 -0
- package/lib/types/client/session-location.d.ts +63 -0
- package/lib/types/client/store.d.ts +58 -0
- package/lib/types/commands.d.ts +69 -0
- package/lib/types/driver-core/context-files.d.ts +62 -0
- package/lib/types/driver-core/ownership.d.ts +40 -0
- package/lib/types/driver-core/permission-knobs.d.ts +26 -0
- package/lib/types/driver-core/prompt.d.ts +23 -0
- package/lib/types/driver-core/skill-inject.d.ts +59 -0
- package/lib/types/engine-claude/agent.d.ts +116 -0
- package/lib/types/engine-claude/loop.d.ts +99 -0
- package/lib/types/engine-claude/mapping.d.ts +84 -0
- package/lib/types/engine-claude/permission.d.ts +41 -0
- package/lib/types/engine-claude/process.d.ts +59 -0
- package/lib/types/engine-claude/provider-env.d.ts +50 -0
- package/lib/types/engine-claude/sdk.d.ts +101 -0
- package/lib/types/engine-claude/types.d.ts +28 -0
- package/lib/types/engine-codex/agent.d.ts +109 -0
- package/lib/types/engine-codex/appserver/client.d.ts +49 -0
- package/lib/types/engine-codex/appserver/mapping.d.ts +67 -0
- package/lib/types/engine-codex/appserver/thread.d.ts +66 -0
- package/lib/types/engine-codex/appserver/types.d.ts +215 -0
- package/lib/types/engine-codex/loop.d.ts +92 -0
- package/lib/types/engine-codex/permission.d.ts +32 -0
- package/lib/types/engine-codex/skills.d.ts +29 -0
- package/lib/types/engine-codex/types.d.ts +19 -0
- package/lib/types/engine-pi/agent.d.ts +125 -0
- package/lib/types/engine-pi/loop.d.ts +96 -0
- package/lib/types/engine-pi/permission.d.ts +43 -0
- package/lib/types/engine-pi/rpc/client.d.ts +105 -0
- package/lib/types/engine-pi/rpc/mapping.d.ts +37 -0
- package/lib/types/engine-pi/rpc/types.d.ts +235 -0
- package/lib/types/engine-pi/skills.d.ts +55 -0
- package/lib/types/engine-pi/types.d.ts +27 -0
- package/lib/types/engine-record.d.ts +124 -0
- package/lib/types/index.d.ts +138 -0
- package/lib/types/invariant.d.ts +23 -0
- package/lib/types/llm-compat.d.ts +32 -0
- package/lib/types/namespace.d.ts +19 -0
- package/lib/types/patch-manager.d.ts +78 -0
- package/lib/types/router.d.ts +189 -0
- package/lib/types/rpc.d.ts +113 -0
- package/lib/types/settings.d.ts +29 -0
- package/lib/types/skills.d.ts +93 -0
- package/package.json +107 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vidge
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# dsh-agent-hub
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vidge/dsh-agent-hub)
|
|
4
|
+
|
|
5
|
+
Run any agent loop engine on **dsh** — the built-in in-process loop, Claude
|
|
6
|
+
Code, Codex, or Pi — **chosen per session**, all sharing dsh's own session
|
|
7
|
+
store, message format, model routing, and tracing.
|
|
8
|
+
|
|
9
|
+
Pick an engine the way you pick a model: in the composer, when you start a
|
|
10
|
+
session. The session you are in keeps running on the engine it was created
|
|
11
|
+
with. No restart, no global switch, no interrupted work.
|
|
12
|
+
|
|
13
|
+
## Why a hub
|
|
14
|
+
|
|
15
|
+
dsh admits exactly one `AgentFactory` for the whole process. That single slot
|
|
16
|
+
is what forced every earlier approach to be a *global* choice: to run Claude
|
|
17
|
+
Code you had to disable the base loop, and every session in the profile moved
|
|
18
|
+
with you.
|
|
19
|
+
|
|
20
|
+
This plugin takes that slot and turns it into a router. It holds one factory
|
|
21
|
+
per engine — including dsh's own in-process loop, mounted as a first-class
|
|
22
|
+
engine rather than replaced — and dispatches each `createAgent` / `resume` call
|
|
23
|
+
to the engine that session belongs to.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
dsh harness (session · llm · tracing · model routing)
|
|
27
|
+
│
|
|
28
|
+
│ the one AgentFactory slot
|
|
29
|
+
▼
|
|
30
|
+
LoopEngineRouter
|
|
31
|
+
├── in-process → @deepseek-ai/dsh-agent-loop (hosted, not replaced)
|
|
32
|
+
├── claude-code → Claude Agent SDK
|
|
33
|
+
├── codex → codex app-server
|
|
34
|
+
└── pi → pi --mode rpc
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Everything above the router stays dsh's. Each engine's native output is
|
|
38
|
+
translated into dsh's `Message` / `ContentBlock` / `StreamChunk` types, so
|
|
39
|
+
sessions from different engines are stored, streamed, resumed, and traced
|
|
40
|
+
identically.
|
|
41
|
+
|
|
42
|
+
### Engine affinity is durable
|
|
43
|
+
|
|
44
|
+
A session's engine is recorded when it is created and travels with it. Resuming
|
|
45
|
+
a session restores it to the engine that produced its history — not to whatever
|
|
46
|
+
is currently selected. This matters because engine session logs carry different
|
|
47
|
+
provenance (a Codex-driven session records `provider = 'codex'`), and replaying
|
|
48
|
+
that history under another engine would hand the model a transcript it cannot
|
|
49
|
+
act on.
|
|
50
|
+
|
|
51
|
+
Forked sessions and subagents inherit the parent's engine.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
dsh plugin --profile web add @vidge/dsh-agent-hub
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Restart `dsh web` once after installing. After that, engine selection is
|
|
60
|
+
runtime state — switching never requires a restart again.
|
|
61
|
+
|
|
62
|
+
> Installing writes a small managed block into the profile's
|
|
63
|
+
> `cordis.patch.yml`, disabling the bundle's own `agent-loop` row so the router
|
|
64
|
+
> can take the factory slot and re-mount that loop itself. Everything else in
|
|
65
|
+
> that file is preserved byte for byte.
|
|
66
|
+
|
|
67
|
+
### Requirements
|
|
68
|
+
|
|
69
|
+
Only for the engines you actually use:
|
|
70
|
+
|
|
71
|
+
- **Claude Code** — the Claude Code CLI installed on the host. Credentials are
|
|
72
|
+
derived from dsh's own LLM provider configuration (see below); a CLI login is
|
|
73
|
+
a fallback, not a requirement.
|
|
74
|
+
- **Codex** — authenticated via `codex login`, or a `CODEX_API_KEY` entry.
|
|
75
|
+
- **Pi** — authenticated the way `pi` expects: its own `~/.pi/agent/auth.json`,
|
|
76
|
+
or the provider's API-key environment variable.
|
|
77
|
+
|
|
78
|
+
The in-process engine needs nothing beyond dsh itself.
|
|
79
|
+
|
|
80
|
+
## Usage
|
|
81
|
+
|
|
82
|
+
Choose an engine in the composer when starting a session. To change engines,
|
|
83
|
+
start a new session — the current one keeps its engine, and anything still
|
|
84
|
+
running on it is undisturbed.
|
|
85
|
+
|
|
86
|
+
**Settings → Loop engine** sets the default for new sessions and controls
|
|
87
|
+
whether the composer picker is shown.
|
|
88
|
+
|
|
89
|
+
To remove the plugin:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
dsh plugin --profile web remove @vidge/dsh-agent-hub
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Then restart `dsh web`.
|
|
96
|
+
|
|
97
|
+
## Model and credential routing
|
|
98
|
+
|
|
99
|
+
For the Claude Code engine, the child process's provider environment is derived
|
|
100
|
+
from dsh's own LLM configuration rather than inherited from the shell that
|
|
101
|
+
launched the host. The selected model names a provider route; the plugin reads
|
|
102
|
+
that route's endpoint from `llm-pi-ai` settings, resolves its key through dsh's
|
|
103
|
+
`credentials` service, and states the result as the environment variables the
|
|
104
|
+
Agent SDK understands — Bedrock (including behind a corporate gateway) and
|
|
105
|
+
native Anthropic endpoints.
|
|
106
|
+
|
|
107
|
+
This is why a dsh started from a desktop launcher works: it inherits no
|
|
108
|
+
provider variables, but it does not need to. dsh already knows the answer.
|
|
109
|
+
|
|
110
|
+
When a route cannot be derived — an OpenAI-protocol provider with no Claude
|
|
111
|
+
Code equivalent, an unset credential — the plugin falls back to inherited
|
|
112
|
+
environment and reports what the child was actually pointed at.
|
|
113
|
+
|
|
114
|
+
## Engine notes
|
|
115
|
+
|
|
116
|
+
- **Claude Code** runs one SDK query per dsh step. Its slash commands are
|
|
117
|
+
bridged into the web menu (built-ins plus user-level `~/.claude/commands/`)
|
|
118
|
+
and forwarded to the engine, which expands them natively. Project-level
|
|
119
|
+
`.claude/commands/` files stay engine-side and work when typed directly.
|
|
120
|
+
- **Codex** runs `codex app-server` and has no interactive tool approval —
|
|
121
|
+
permissions come from the session's `sandboxMode` + `approvalPolicy`. Its
|
|
122
|
+
`AGENTS.md` files are surfaced through the dsh skill-injection seam across
|
|
123
|
+
every directory from the session cwd up to the git root, plus
|
|
124
|
+
`~/.codex/AGENTS.md`.
|
|
125
|
+
- **Pi** runs `pi --mode rpc`. Pi has no permission system, so the whole child
|
|
126
|
+
is sandboxed through the dsh subprocess service (default `read-only`). Its
|
|
127
|
+
context files (`AGENTS.md` / `CLAUDE.md`, with `AGENTS.override.md`
|
|
128
|
+
preferred, plus the user-level file under the pi config dir) and its
|
|
129
|
+
`skills/` catalogs are surfaced through the same seam.
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# dsh-agent-hub
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vidge/dsh-agent-hub)
|
|
4
|
+
|
|
5
|
+
在 **dsh** 上运行任意 agent loop 引擎——内置的 in-process loop、Claude Code、
|
|
6
|
+
Codex、Pi——**按会话选择**,并且全部共用 dsh 自己的会话存储、消息格式、模型调度
|
|
7
|
+
与链路追踪。
|
|
8
|
+
|
|
9
|
+
像选模型一样选引擎:在 composer 里选,开一个新会话。当前会话仍跑在它创建时的引擎
|
|
10
|
+
上。不用重启,不是全局切换,不会打断正在进行的工作。
|
|
11
|
+
|
|
12
|
+
## 为什么是 hub
|
|
13
|
+
|
|
14
|
+
dsh 整个进程只允许一个 `AgentFactory`。正是这个唯一槽位,使得以往所有做法都只能是
|
|
15
|
+
**全局**选择:要跑 Claude Code 就得禁掉 base loop,profile 里的每个会话都被一起
|
|
16
|
+
带走。
|
|
17
|
+
|
|
18
|
+
本插件占住那个槽位,并把它变成一个路由器。它为每个引擎持有一个 factory——**包括
|
|
19
|
+
dsh 自己的 in-process loop,它是被托管为一等引擎,而不是被替换**——并把每次
|
|
20
|
+
`createAgent` / `resume` 调用分发给该会话所属的引擎。
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
dsh harness (会话 · llm · 追踪 · 模型调度)
|
|
24
|
+
│
|
|
25
|
+
│ 唯一的 AgentFactory 槽位
|
|
26
|
+
▼
|
|
27
|
+
LoopEngineRouter
|
|
28
|
+
├── in-process → @deepseek-ai/dsh-agent-loop (托管,非替换)
|
|
29
|
+
├── claude-code → Claude Agent SDK
|
|
30
|
+
├── codex → codex app-server
|
|
31
|
+
└── pi → pi --mode rpc
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
路由器之上的一切仍然是 dsh 的。各引擎的原生输出会被翻译成 dsh 的 `Message` /
|
|
35
|
+
`ContentBlock` / `StreamChunk` 类型,因此不同引擎产生的会话在存储、流式推送、恢复
|
|
36
|
+
和追踪上表现完全一致。
|
|
37
|
+
|
|
38
|
+
### 引擎归属是持久的
|
|
39
|
+
|
|
40
|
+
会话的引擎在创建时被记录,并随会话一起流转。恢复会话时会回到产生这段历史的引擎,
|
|
41
|
+
而不是当前选中的引擎。这一点很重要:各引擎的会话日志 provenance 不同(Codex 驱动
|
|
42
|
+
的会话记录 `provider = 'codex'`),跨引擎重放会把一段模型无法据以行动的历史交给它。
|
|
43
|
+
|
|
44
|
+
fork 出的会话与 subagent 会继承父会话的引擎。
|
|
45
|
+
|
|
46
|
+
## 安装
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
dsh plugin --profile web add @vidge/dsh-agent-hub
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
安装后重启一次 `dsh web`。此后引擎选择即为运行时状态——再也不需要因切换而重启。
|
|
53
|
+
|
|
54
|
+
> 安装会在 profile 的 `cordis.patch.yml` 中写入一小段托管块,禁用 bundle 自带的
|
|
55
|
+
> `agent-loop` 行,以便路由器接管 factory 槽位并由它自己重新挂载该 loop。文件中
|
|
56
|
+
> 其余内容逐字节保留。
|
|
57
|
+
|
|
58
|
+
### 依赖要求
|
|
59
|
+
|
|
60
|
+
仅针对你实际使用的引擎:
|
|
61
|
+
|
|
62
|
+
- **Claude Code** —— 宿主机安装 Claude Code CLI。凭证由 dsh 自身的 LLM provider
|
|
63
|
+
配置派生(见下文);CLI 登录只是兜底,不是必需。
|
|
64
|
+
- **Codex** —— 通过 `codex login` 认证,或提供 `CODEX_API_KEY`。
|
|
65
|
+
- **Pi** —— 按 pi 自己的方式认证:`~/.pi/agent/auth.json`,或对应 provider 的
|
|
66
|
+
API-key 环境变量。
|
|
67
|
+
|
|
68
|
+
in-process 引擎除 dsh 本身外无任何额外要求。
|
|
69
|
+
|
|
70
|
+
## 使用
|
|
71
|
+
|
|
72
|
+
在 composer 中开始会话时选择引擎。要换引擎,开一个新会话——当前会话保持它的引擎,
|
|
73
|
+
仍在其上运行的任务不受影响。
|
|
74
|
+
|
|
75
|
+
**设置 → Loop engine** 用于设定新会话的默认引擎,以及控制是否显示 composer 选择器。
|
|
76
|
+
|
|
77
|
+
卸载插件:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
dsh plugin --profile web remove @vidge/dsh-agent-hub
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
然后重启 `dsh web`。
|
|
84
|
+
|
|
85
|
+
## 模型与凭证路由
|
|
86
|
+
|
|
87
|
+
对 Claude Code 引擎,子进程的 provider 环境变量由 **dsh 自身的 LLM 配置派生**,
|
|
88
|
+
而不是从启动宿主的 shell 继承。选中的模型指明一条 provider 路由,插件从
|
|
89
|
+
`llm-pi-ai` 设置中读取该路由的 endpoint,通过 dsh 的 `credentials` 服务解析其密钥,
|
|
90
|
+
再把结果表述为 Agent SDK 能理解的环境变量——支持 Bedrock(含企业网关场景)与原生
|
|
91
|
+
Anthropic endpoint。
|
|
92
|
+
|
|
93
|
+
这正是从桌面启动器启动的 dsh 也能工作的原因:它没有继承任何 provider 变量,但它
|
|
94
|
+
不需要。dsh 自己就知道答案。
|
|
95
|
+
|
|
96
|
+
当路由无法派生时——例如没有 Claude Code 对应实现的 OpenAI 协议 provider、或凭证
|
|
97
|
+
未配置——插件会回退到继承环境,并报告子进程实际被指向了哪里。
|
|
98
|
+
|
|
99
|
+
## 各引擎说明
|
|
100
|
+
|
|
101
|
+
- **Claude Code** 每个 dsh step 运行一次 SDK query。其斜杠命令被桥接进 web 菜单
|
|
102
|
+
(内置命令加上用户级 `~/.claude/commands/`)并转发给引擎原生展开。项目级
|
|
103
|
+
`.claude/commands/` 文件保留在引擎侧,直接输入即可使用。
|
|
104
|
+
- **Codex** 运行 `codex app-server`,没有交互式工具审批——权限来自会话的
|
|
105
|
+
`sandboxMode` + `approvalPolicy`。其 `AGENTS.md` 指令文件通过 dsh 的
|
|
106
|
+
skill-injection 接缝暴露,覆盖从会话 cwd 到 git 根目录的每一层,外加
|
|
107
|
+
`~/.codex/AGENTS.md`。
|
|
108
|
+
- **Pi** 运行 `pi --mode rpc`。Pi 没有权限系统,因此整个子进程通过 dsh subprocess
|
|
109
|
+
服务沙箱化(默认 `read-only`)。其上下文文件(`AGENTS.md` / `CLAUDE.md`,
|
|
110
|
+
优先 `AGENTS.override.md`,加上 pi 配置目录下的用户级文件)与 `skills/` 目录
|
|
111
|
+
通过同一接缝暴露。
|
|
112
|
+
|
|
113
|
+
## 许可
|
|
114
|
+
|
|
115
|
+
MIT
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Bundle patch layer of @vidge/dsh-agent-hub, applied when the loader expands
|
|
2
|
+
# this bundle — before any plugin's apply() runs. Both rows must live here.
|
|
3
|
+
#
|
|
4
|
+
# Disabling `agent-loop` is a BOOT-TIME fact, not something this plugin can do
|
|
5
|
+
# at runtime. The harness admits exactly one AgentFactory, and the base loop's
|
|
6
|
+
# constructor claims it via `ctx.agents.setFactory(this)` while the loader is
|
|
7
|
+
# still expanding entries — strictly before `loop-engine` applies. A profile
|
|
8
|
+
# that leaves the row enabled therefore fails the whole plugin tree with
|
|
9
|
+
# "an agent factory is already registered" and never reaches the router. The
|
|
10
|
+
# managed block this plugin writes into the profile's own cordis.patch.yml
|
|
11
|
+
# cannot substitute: that layer is applied after the bundle, and the write
|
|
12
|
+
# itself happens in apply(), by which point AgentLoop has already registered.
|
|
13
|
+
#
|
|
14
|
+
# The base loop is not lost by being disabled here — `mountBaseLoop` hosts it
|
|
15
|
+
# behind the router as the `in-process` engine, through a context that
|
|
16
|
+
# redirects its setFactory into router registration.
|
|
17
|
+
- id: agent-loop
|
|
18
|
+
disabled: true
|
|
19
|
+
|
|
20
|
+
- insert:
|
|
21
|
+
- id: loop-engine
|
|
22
|
+
name: '@vidge/dsh-agent-hub'
|