ds-harness-remote 0.3.8
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 +103 -0
- package/cordis.patch.yml +7 -0
- package/dist/adapters/agent-adapter.d.ts +35 -0
- package/dist/adapters/agent-adapter.d.ts.map +1 -0
- package/dist/adapters/agent-adapter.js +80 -0
- package/dist/adapters/agent-adapter.js.map +1 -0
- package/dist/adapters/permission-adapter.d.ts +13 -0
- package/dist/adapters/permission-adapter.d.ts.map +1 -0
- package/dist/adapters/permission-adapter.js +67 -0
- package/dist/adapters/permission-adapter.js.map +1 -0
- package/dist/adapters/session-adapter.d.ts +38 -0
- package/dist/adapters/session-adapter.d.ts.map +1 -0
- package/dist/adapters/session-adapter.js +230 -0
- package/dist/adapters/session-adapter.js.map +1 -0
- package/dist/adapters/workspace-adapter.d.ts +13 -0
- package/dist/adapters/workspace-adapter.d.ts.map +1 -0
- package/dist/adapters/workspace-adapter.js +21 -0
- package/dist/adapters/workspace-adapter.js.map +1 -0
- package/dist/api-proxy-switch.d.ts +33 -0
- package/dist/api-proxy-switch.d.ts.map +1 -0
- package/dist/api-proxy-switch.js +107 -0
- package/dist/api-proxy-switch.js.map +1 -0
- package/dist/bin/doctor.d.ts +3 -0
- package/dist/bin/doctor.d.ts.map +1 -0
- package/dist/bin/doctor.js +13 -0
- package/dist/bin/doctor.js.map +1 -0
- package/dist/client-runtime.d.ts +98 -0
- package/dist/client-runtime.d.ts.map +1 -0
- package/dist/client-runtime.js +421 -0
- package/dist/client-runtime.js.map +1 -0
- package/dist/client-secure-transport.d.ts +22 -0
- package/dist/client-secure-transport.d.ts.map +1 -0
- package/dist/client-secure-transport.js +129 -0
- package/dist/client-secure-transport.js.map +1 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.github.js +2938 -0
- package/dist/client.js +2938 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/connection-controller.d.ts +39 -0
- package/dist/connection-controller.d.ts.map +1 -0
- package/dist/connection-controller.js +170 -0
- package/dist/connection-controller.js.map +1 -0
- package/dist/control-runtime.d.ts +36 -0
- package/dist/control-runtime.d.ts.map +1 -0
- package/dist/control-runtime.js +265 -0
- package/dist/control-runtime.js.map +1 -0
- package/dist/event-sequencer.d.ts +23 -0
- package/dist/event-sequencer.d.ts.map +1 -0
- package/dist/event-sequencer.js +54 -0
- package/dist/event-sequencer.js.map +1 -0
- package/dist/harness-api-bridge.d.ts +55 -0
- package/dist/harness-api-bridge.d.ts.map +1 -0
- package/dist/harness-api-bridge.js +387 -0
- package/dist/harness-api-bridge.js.map +1 -0
- package/dist/identity-store.d.ts +45 -0
- package/dist/identity-store.d.ts.map +1 -0
- package/dist/identity-store.js +183 -0
- package/dist/identity-store.js.map +1 -0
- package/dist/ids.d.ts +2 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +17 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16091 -0
- package/dist/index.js.map +7 -0
- package/dist/logging.d.ts +18 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +30 -0
- package/dist/logging.js.map +1 -0
- package/dist/pairing-controller.d.ts +52 -0
- package/dist/pairing-controller.d.ts.map +1 -0
- package/dist/pairing-controller.js +73 -0
- package/dist/pairing-controller.js.map +1 -0
- package/dist/pending-approvals.d.ts +14 -0
- package/dist/pending-approvals.d.ts.map +1 -0
- package/dist/pending-approvals.js +52 -0
- package/dist/pending-approvals.js.map +1 -0
- package/dist/remote-api-proxy.d.ts +12 -0
- package/dist/remote-api-proxy.d.ts.map +1 -0
- package/dist/remote-api-proxy.js +191 -0
- package/dist/remote-api-proxy.js.map +1 -0
- package/dist/remote-directory-browser.d.ts +16 -0
- package/dist/remote-directory-browser.d.ts.map +1 -0
- package/dist/remote-directory-browser.js +48 -0
- package/dist/remote-directory-browser.js.map +1 -0
- package/dist/rpc-router.d.ts +21 -0
- package/dist/rpc-router.d.ts.map +1 -0
- package/dist/rpc-router.js +93 -0
- package/dist/rpc-router.js.map +1 -0
- package/dist/server-api.d.ts +80 -0
- package/dist/server-api.d.ts.map +1 -0
- package/dist/server-api.js +405 -0
- package/dist/server-api.js.map +1 -0
- package/dist/server-connection.d.ts +70 -0
- package/dist/server-connection.d.ts.map +1 -0
- package/dist/server-connection.js +759 -0
- package/dist/server-connection.js.map +1 -0
- package/dist/server-credentials.d.ts +46 -0
- package/dist/server-credentials.d.ts.map +1 -0
- package/dist/server-credentials.js +71 -0
- package/dist/server-credentials.js.map +1 -0
- package/dist/service.d.ts +56 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +162 -0
- package/dist/service.js.map +1 -0
- package/dist/typert-gateway-switch.d.ts +19 -0
- package/dist/typert-gateway-switch.d.ts.map +1 -0
- package/dist/typert-gateway-switch.js +41 -0
- package/dist/typert-gateway-switch.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +12 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +12 -0
- package/dist/version.js.map +1 -0
- package/dist/werift-rtc.d.ts +85 -0
- package/dist/werift-rtc.d.ts.map +1 -0
- package/dist/werift-rtc.js +164 -0
- package/dist/werift-rtc.js.map +1 -0
- package/package.json +98 -0
- package/public.d.ts +19 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DSH Remote contributors
|
|
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,103 @@
|
|
|
1
|
+
# ds-harness-remote
|
|
2
|
+
|
|
3
|
+
DeepSeek Harness 的 Host + Remote 工作区插件。一次安装同时提供:
|
|
4
|
+
|
|
5
|
+
- Host runtime:让当前 Harness 接受来自自有设备的加密远程操作。
|
|
6
|
+
- Remote workspace:在当前 Harness UI 中选择另一台 Host 及其工作区。
|
|
7
|
+
|
|
8
|
+
用户不需要启动或切换 Client 模式。选择 Remote 工作区后,本地 Web UI 保持不变,稳定的 `ApiProxySwitch` 将新请求路由到远端 `RemoteHarnessApiProxy`;断线或退出时恢复本地 ApiProxy。
|
|
9
|
+
|
|
10
|
+
## 用户流程
|
|
11
|
+
|
|
12
|
+
1. 在插件设置中配置 Server,并用网页生成的一次性设备授权码注册 Host;独立 Remote 身份通过 `owned_device` 自动继承账号归属。
|
|
13
|
+
2. 从侧边栏 **Remote** 打开模态框。
|
|
14
|
+
3. 选择同账号的在线 Host。当前 Host 会被排除;列表显示 macOS、Windows 或 Linux,以及 Harness 和插件版本。
|
|
15
|
+
4. 选择已有 Workspace,或点击 **+** 浏览远端目录并创建 Workspace。
|
|
16
|
+
5. 进入远程工作区后,通过顶部 Header 查看主机、LAN/P2P/TURN/Relay 路径和端到端加密状态;点击 **退出** 回到本地。
|
|
17
|
+
|
|
18
|
+
## 目录浏览
|
|
19
|
+
|
|
20
|
+
Remote picker 首先调用远端 Harness 的 `host.listDirectory`。若远端 Harness 组合的是桌面 `native` picker,插件 Host bridge 会在已认证、端到端加密的连接内提供只读目录元数据兜底。
|
|
21
|
+
|
|
22
|
+
目录能力仅返回单层子目录、绝对路径、面包屑、Home 路径和隐藏标志,并限制单次结果数量。它不读取文件内容,不提供文件操作,也不允许创建、修改或删除目录。
|
|
23
|
+
|
|
24
|
+
## 架构
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
本地 Harness UI
|
|
28
|
+
-> ApiProxySwitch
|
|
29
|
+
-> RemoteHarnessApiProxy
|
|
30
|
+
-> Adaptive transport (LAN / P2P / TURN / Relay)
|
|
31
|
+
-> Noise IK secure channel
|
|
32
|
+
-> HarnessApiBridge allowlist
|
|
33
|
+
-> 远端 Harness ApiProxy
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
主要模块:
|
|
37
|
+
|
|
38
|
+
- `service.ts`:Host runtime 与连接生命周期。
|
|
39
|
+
- `client-runtime.ts`:设备列表、连接、远程目录和 Workspace 操作。
|
|
40
|
+
- `client.ts`:设置卡片、Remote 模态框、侧边栏入口和远程 Header。
|
|
41
|
+
- `harness-api-bridge.ts`:固定 ApiProxy allowlist、unary、respond 与 stream bridge。
|
|
42
|
+
- `remote-directory-browser.ts`:native picker 场景下的只读目录兜底。
|
|
43
|
+
- `server-api.ts` / `server-connection.ts`:账号设备 API 与 Host 控制连接。
|
|
44
|
+
- `identity-store.ts` / `server-credentials.ts`:按 Server origin 和角色隔离的身份与凭证。
|
|
45
|
+
|
|
46
|
+
## 安全模型
|
|
47
|
+
|
|
48
|
+
- Host 只建立出站 HTTPS/WSS 连接,不监听公网端口。
|
|
49
|
+
- Host 与 Client 使用长期 X25519 identity key 和 Noise IK 相互认证。
|
|
50
|
+
- Server membership 和本地 pinned peer key 必须同时匹配。
|
|
51
|
+
- 每个 Client connection 拥有独立的 secure channel、RPC pending 和 stream registry。
|
|
52
|
+
- ApiProxy method 必须命中代码内 allowlist;未知或敏感方法 fail closed。
|
|
53
|
+
- 禁止 Shell、PTY、远程桌面、credentials/settings、native open/picker、目录写入、文件内容、attachment、download 和 Cordis service 反射。
|
|
54
|
+
|
|
55
|
+
身份数据位于 `$DSH_HOME/remote/servers/<origin-hash>/{host,client}`。Unix 私钥必须为 `0600`;损坏或权限过宽的 key 会被拒绝,不会静默替换。
|
|
56
|
+
|
|
57
|
+
## 配置
|
|
58
|
+
|
|
59
|
+
插件设置写入 `$DSH_HOME/settings.yaml` 的 `dsh-remote` namespace,重启后应用。也可以设置:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
export DSH_REMOTE_SERVER=https://dsh.r2049.cn
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
生产 Server 必须使用 HTTPS/WSS。Host 和 Remote 身份使用独立 deviceId、identity key 和 token,但可以通过 `register-owned-role` 继承同一账号归属。
|
|
66
|
+
|
|
67
|
+
## 安装与构建
|
|
68
|
+
|
|
69
|
+
DSH Desktop GitHub 安装:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
github:liguobao/deepseek-harness-remote#v0.2.23
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
本地验证:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
pnpm --filter ds-harness-remote check
|
|
79
|
+
pnpm --filter ds-harness-remote test
|
|
80
|
+
pnpm --filter ds-harness-remote build
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
根包提供 GitHub Bundle manifest;本包是 npm 发布和 CI artifact 边界。构建会生成 `dist/index.js`、`dist/client.js` 和 GitHub client bundle。
|
|
84
|
+
|
|
85
|
+
## 发布与版本一致性要求
|
|
86
|
+
|
|
87
|
+
发布新版本前必须同步以下版本号:
|
|
88
|
+
|
|
89
|
+
- 根目录 `package.json` 的 `version`
|
|
90
|
+
- `packages/plugin/package.json` 的 `version`
|
|
91
|
+
- `packages/plugin/src/version.ts` 中的 `PLUGIN_VERSION`
|
|
92
|
+
|
|
93
|
+
`packages/plugin/scripts/verify-version-sync.mjs` 会在 `check/build/test` 前校验这三处是否一致。任一不一致将导致构建失败。
|
|
94
|
+
|
|
95
|
+
建议发布步骤:
|
|
96
|
+
|
|
97
|
+
1. 同步更新上述三个版本号。
|
|
98
|
+
2. 运行 `pnpm --filter ds-harness-remote check`。
|
|
99
|
+
3. 通过后再执行 `pnpm --filter ds-harness-remote build` 与 `test`。
|
|
100
|
+
|
|
101
|
+
## 兼容边界
|
|
102
|
+
|
|
103
|
+
Plugin 使用官方 `@deepseek-ai/dsh-host-apiproxy/api`,不维护第二套 Session、Event 或 Permission 协议。Server、Remote Web 和 Admin runtime 不在本仓库实现。协议详情见 [Remote Protocol](../../docs/protocol.md),Server 接入见 [Plugin integration](../../docs/plugin-integration.md)。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Session } from '@deepseek-ai/dsh-session';
|
|
2
|
+
import type { AgentRegistry } from '@deepseek-ai/dsh-agent';
|
|
3
|
+
interface SessionTitleService {
|
|
4
|
+
rename(session: Session, title: string): unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare class AgentAdapter {
|
|
7
|
+
private readonly agents;
|
|
8
|
+
private readonly titles?;
|
|
9
|
+
private readonly created;
|
|
10
|
+
private readonly delivered;
|
|
11
|
+
constructor(agents: AgentRegistry, titles?: SessionTitleService | undefined);
|
|
12
|
+
create(params: {
|
|
13
|
+
clientRequestId: string;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
title?: string | null;
|
|
16
|
+
}): Promise<Session>;
|
|
17
|
+
send(params: {
|
|
18
|
+
sessionId: string;
|
|
19
|
+
clientMessageId: string;
|
|
20
|
+
text: string;
|
|
21
|
+
}): {
|
|
22
|
+
accepted: true;
|
|
23
|
+
clientMessageId: string;
|
|
24
|
+
};
|
|
25
|
+
stop(sessionId: string): {
|
|
26
|
+
accepted: true;
|
|
27
|
+
};
|
|
28
|
+
private pruneCreated;
|
|
29
|
+
}
|
|
30
|
+
export declare class AgentAdapterError extends Error {
|
|
31
|
+
readonly code: string;
|
|
32
|
+
constructor(code: string, message: string);
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=agent-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/agent-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAG3D,UAAU,mBAAmB;IAC3B,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjD;AAED,qBAAa,YAAY;IAIX,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAiB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAH5E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAEjB,MAAM,EAAE,aAAa,EAAmB,MAAM,CAAC,EAAE,mBAAmB,YAAA;IAE3F,MAAM,CAAC,MAAM,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBxG,IAAI,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;IAsBvH,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE;IAO3C,OAAO,CAAC,YAAY;CAGrB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CACnD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
3
|
+
import { uuidV7 } from '../ids.js';
|
|
4
|
+
export class AgentAdapter {
|
|
5
|
+
agents;
|
|
6
|
+
titles;
|
|
7
|
+
created = new Map();
|
|
8
|
+
delivered = new Set();
|
|
9
|
+
constructor(agents, titles) {
|
|
10
|
+
this.agents = agents;
|
|
11
|
+
this.titles = titles;
|
|
12
|
+
}
|
|
13
|
+
async create(params) {
|
|
14
|
+
const existingId = this.created.get(params.clientRequestId);
|
|
15
|
+
if (existingId !== undefined) {
|
|
16
|
+
const existing = this.agents.get(SessionId(existingId));
|
|
17
|
+
if (existing !== undefined)
|
|
18
|
+
return existing.session;
|
|
19
|
+
this.created.delete(params.clientRequestId);
|
|
20
|
+
}
|
|
21
|
+
const sessionId = SessionId(`session-${uuidV7()}`);
|
|
22
|
+
const handle = await this.agents.create({
|
|
23
|
+
sessionId,
|
|
24
|
+
...(params.cwd === undefined ? {} : { meta: { cwd: params.cwd } }),
|
|
25
|
+
});
|
|
26
|
+
if (params.title !== undefined && params.title !== null)
|
|
27
|
+
this.titles?.rename(handle.agent.session, params.title);
|
|
28
|
+
this.created.set(params.clientRequestId, String(sessionId));
|
|
29
|
+
this.pruneCreated();
|
|
30
|
+
return handle.agent.session;
|
|
31
|
+
}
|
|
32
|
+
send(params) {
|
|
33
|
+
const key = `${params.sessionId}\0${params.clientMessageId}`;
|
|
34
|
+
if (this.delivered.has(key))
|
|
35
|
+
return { accepted: true, clientMessageId: params.clientMessageId };
|
|
36
|
+
const agent = this.agents.get(SessionId(params.sessionId));
|
|
37
|
+
if (agent === undefined)
|
|
38
|
+
throw new AgentAdapterError('SESSION_NOT_FOUND', 'The session is no longer available.');
|
|
39
|
+
const message = createUserMessage({
|
|
40
|
+
content: [{ type: 'text', text: params.text }],
|
|
41
|
+
source: { kind: 'user' },
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
if (agent.status === 'idle')
|
|
45
|
+
agent.followup(message);
|
|
46
|
+
else if (agent.status === 'running')
|
|
47
|
+
agent.steer(message);
|
|
48
|
+
else
|
|
49
|
+
throw new AgentAdapterError('SESSION_NOT_READY', 'The session is not ready for input.');
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error instanceof AgentAdapterError)
|
|
53
|
+
throw error;
|
|
54
|
+
throw new AgentAdapterError('AGENT_BUSY', 'The agent could not accept the message.');
|
|
55
|
+
}
|
|
56
|
+
this.delivered.add(key);
|
|
57
|
+
if (this.delivered.size > 10_000)
|
|
58
|
+
this.delivered.delete(this.delivered.values().next().value);
|
|
59
|
+
return { accepted: true, clientMessageId: params.clientMessageId };
|
|
60
|
+
}
|
|
61
|
+
stop(sessionId) {
|
|
62
|
+
const agent = this.agents.get(SessionId(sessionId));
|
|
63
|
+
if (agent === undefined)
|
|
64
|
+
throw new AgentAdapterError('SESSION_NOT_FOUND', 'The session is no longer available.');
|
|
65
|
+
agent.cancel({ kind: 'user' }, { keepInbox: true });
|
|
66
|
+
return { accepted: true };
|
|
67
|
+
}
|
|
68
|
+
pruneCreated() {
|
|
69
|
+
while (this.created.size > 1_024)
|
|
70
|
+
this.created.delete(this.created.keys().next().value);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export class AgentAdapterError extends Error {
|
|
74
|
+
code;
|
|
75
|
+
constructor(code, message) {
|
|
76
|
+
super(message);
|
|
77
|
+
this.code = code;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=agent-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-adapter.js","sourceRoot":"","sources":["../../src/adapters/agent-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ApprovalOutcome, ApprovalRequest } from '@deepseek-ai/dsh-user-approval';
|
|
2
|
+
import type { EventSequencer } from '../event-sequencer.js';
|
|
3
|
+
import type { PendingApprovals } from '../pending-approvals.js';
|
|
4
|
+
export declare class PermissionAdapter {
|
|
5
|
+
private readonly pending;
|
|
6
|
+
private readonly events;
|
|
7
|
+
private readonly isRemoteAvailable;
|
|
8
|
+
private readonly emit;
|
|
9
|
+
private readonly timeoutMs;
|
|
10
|
+
constructor(pending: PendingApprovals, events: EventSequencer, isRemoteAvailable: (sessionId: string) => boolean, emit: (event: ReturnType<EventSequencer['publish']>) => void, timeoutMs: number);
|
|
11
|
+
answer(req: ApprovalRequest, next: () => Promise<ApprovalOutcome>): Promise<ApprovalOutcome>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=permission-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/permission-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAEtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAG/D,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAJT,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,cAAc,EACtB,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,EACjD,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,IAAI,EAC5D,SAAS,EAAE,MAAM;IAG9B,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC;CAmBnG"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { uuidV7 } from '../ids.js';
|
|
2
|
+
export class PermissionAdapter {
|
|
3
|
+
pending;
|
|
4
|
+
events;
|
|
5
|
+
isRemoteAvailable;
|
|
6
|
+
emit;
|
|
7
|
+
timeoutMs;
|
|
8
|
+
constructor(pending, events, isRemoteAvailable, emit, timeoutMs) {
|
|
9
|
+
this.pending = pending;
|
|
10
|
+
this.events = events;
|
|
11
|
+
this.isRemoteAvailable = isRemoteAvailable;
|
|
12
|
+
this.emit = emit;
|
|
13
|
+
this.timeoutMs = timeoutMs;
|
|
14
|
+
}
|
|
15
|
+
async answer(req, next) {
|
|
16
|
+
const sessionId = String(req.agent.session.id);
|
|
17
|
+
if (!this.isRemoteAvailable(sessionId))
|
|
18
|
+
return next();
|
|
19
|
+
if (req.signal?.aborted)
|
|
20
|
+
return 'cancelled';
|
|
21
|
+
const permission = permissionContext(req);
|
|
22
|
+
const request = {
|
|
23
|
+
requestId: uuidV7(),
|
|
24
|
+
sessionId,
|
|
25
|
+
toolName: req.toolName,
|
|
26
|
+
...(req.callId === undefined ? {} : { callId: String(req.callId) }),
|
|
27
|
+
...(req.reason === undefined ? {} : { reason: req.reason }),
|
|
28
|
+
permission,
|
|
29
|
+
status: 'pending',
|
|
30
|
+
expiresAt: Date.now() + this.timeoutMs,
|
|
31
|
+
};
|
|
32
|
+
const outcome = this.pending.open(request, req.signal);
|
|
33
|
+
this.emit(this.events.publish('permission.requested', { ...request, sessionId }, sessionId));
|
|
34
|
+
return outcome;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function permissionContext(req) {
|
|
38
|
+
const rawCall = req.callId === undefined
|
|
39
|
+
? undefined
|
|
40
|
+
: [...req.agent.session.events].reverse().find(event => event.type === 'tool/call' && String(event.data.callId) === String(req.callId));
|
|
41
|
+
const input = rawCall?.type === 'tool/call' ? parseObject(rawCall.data.arguments) : undefined;
|
|
42
|
+
const command = stringField(input, 'command') ?? stringField(input, 'cmd');
|
|
43
|
+
const commandTool = /bash|shell|terminal|pwsh|powershell/i.test(req.toolName);
|
|
44
|
+
return {
|
|
45
|
+
kind: commandTool || command !== undefined ? 'command' : 'tool',
|
|
46
|
+
...(command === undefined ? {} : { command }),
|
|
47
|
+
...(req.agent.session.header.cwd === undefined ? {} : { cwd: req.agent.session.header.cwd }),
|
|
48
|
+
toolName: req.toolName,
|
|
49
|
+
...(req.reason === undefined ? {} : { description: req.reason }),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function parseObject(value) {
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(value);
|
|
55
|
+
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
|
|
56
|
+
? parsed
|
|
57
|
+
: undefined;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function stringField(value, key) {
|
|
64
|
+
const field = value?.[key];
|
|
65
|
+
return typeof field === 'string' ? field : undefined;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=permission-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-adapter.js","sourceRoot":"","sources":["../../src/adapters/permission-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAKlC,MAAM,OAAO,iBAAiB;IAET;IACA;IACA;IACA;IACA;IALnB,YACmB,OAAyB,EACzB,MAAsB,EACtB,iBAAiD,EACjD,IAA4D,EAC5D,SAAiB;QAJjB,YAAO,GAAP,OAAO,CAAkB;QACzB,WAAM,GAAN,MAAM,CAAgB;QACtB,sBAAiB,GAAjB,iBAAiB,CAAgC;QACjD,SAAI,GAAJ,IAAI,CAAwD;QAC5D,cAAS,GAAT,SAAS,CAAQ;IACjC,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,GAAoB,EAAE,IAAoC;QACrE,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC9C,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,EAAE,CAAA;QACrD,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO,WAAW,CAAA;QAC3C,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;QACzC,MAAM,OAAO,GAA4B;YACvC,SAAS,EAAE,MAAM,EAAE;YACnB,SAAS;YACT,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;YAC3D,UAAU;YACV,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS;SACvC,CAAA;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QACtD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC,CAAA;QAC5F,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,GAAoB;IAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,KAAK,SAAS;QACtC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACrD,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAC/E,CAAA;IACH,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7F,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC1E,MAAM,WAAW,GAAG,sCAAsC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC7E,OAAO;QACL,IAAI,EAAE,WAAW,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;QAC/D,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7C,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC5F,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;KACjE,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzC,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5E,CAAC,CAAC,MAAiC;YACnC,CAAC,CAAC,SAAS,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAA0C,EAAE,GAAW;IAC1E,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AgentRegistry } from '@deepseek-ai/dsh-agent';
|
|
2
|
+
import { type Session, type SessionEvent, type SessionStore } from '@deepseek-ai/dsh-session';
|
|
3
|
+
import type { EventSequencer } from '../event-sequencer.js';
|
|
4
|
+
import type { PendingApprovals } from '../pending-approvals.js';
|
|
5
|
+
import type { MappedEvent, RemoteSessionSummary, SessionSnapshot } from '../types.js';
|
|
6
|
+
import type { WorkspaceAdapter } from './workspace-adapter.js';
|
|
7
|
+
interface SessionTitleService {
|
|
8
|
+
get(session: Session): {
|
|
9
|
+
title: string;
|
|
10
|
+
} | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare class SessionAdapter {
|
|
13
|
+
private readonly sessions;
|
|
14
|
+
private readonly agents;
|
|
15
|
+
private readonly workspaces;
|
|
16
|
+
private readonly pending;
|
|
17
|
+
private readonly sequencer;
|
|
18
|
+
private readonly titles?;
|
|
19
|
+
private readonly streams;
|
|
20
|
+
constructor(sessions: SessionStore, agents: AgentRegistry, workspaces: WorkspaceAdapter, pending: PendingApprovals, sequencer: EventSequencer, titles?: SessionTitleService | undefined);
|
|
21
|
+
list(cursor?: string | null, limit?: number): {
|
|
22
|
+
items: RemoteSessionSummary[];
|
|
23
|
+
nextCursor: string | null;
|
|
24
|
+
};
|
|
25
|
+
get(sessionId: string): SessionSnapshot;
|
|
26
|
+
workspace(sessionId?: string): import("./workspace-adapter.js").RemoteWorkspaceInfo | null;
|
|
27
|
+
summary(session: Session): RemoteSessionSummary;
|
|
28
|
+
mapEvent(session: Session, event: SessionEvent): MappedEvent[];
|
|
29
|
+
private mapChunk;
|
|
30
|
+
private mapAssistantMessage;
|
|
31
|
+
private requireSession;
|
|
32
|
+
}
|
|
33
|
+
export declare class SessionAdapterError extends Error {
|
|
34
|
+
readonly code: string;
|
|
35
|
+
constructor(code: string, message: string);
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=session-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/session-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAa,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAuB,oBAAoB,EAAkB,eAAe,EAAE,MAAM,aAAa,CAAA;AAC1H,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAE9D,UAAU,mBAAmB;IAC3B,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;CACrD;AAID,qBAAa,cAAc;IAIvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAR1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;gBAGtC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,gBAAgB,EAC5B,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,cAAc,EACzB,MAAM,CAAC,EAAE,mBAAmB,YAAA;IAG/C,IAAI,CAAC,MAAM,GAAE,MAAM,GAAG,IAAW,EAAE,KAAK,SAAK,GAAG;QAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;IAO5G,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe;IAavC,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM;IAI5B,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB;IAc/C,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,EAAE;IAuB9D,OAAO,CAAC,QAAQ;IAyBhB,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,cAAc;CAKvB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CACnD"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
2
|
+
export class SessionAdapter {
|
|
3
|
+
sessions;
|
|
4
|
+
agents;
|
|
5
|
+
workspaces;
|
|
6
|
+
pending;
|
|
7
|
+
sequencer;
|
|
8
|
+
titles;
|
|
9
|
+
streams = new Map();
|
|
10
|
+
constructor(sessions, agents, workspaces, pending, sequencer, titles) {
|
|
11
|
+
this.sessions = sessions;
|
|
12
|
+
this.agents = agents;
|
|
13
|
+
this.workspaces = workspaces;
|
|
14
|
+
this.pending = pending;
|
|
15
|
+
this.sequencer = sequencer;
|
|
16
|
+
this.titles = titles;
|
|
17
|
+
}
|
|
18
|
+
list(cursor = null, limit = 50) {
|
|
19
|
+
const all = this.sessions.list().map(session => this.summary(session));
|
|
20
|
+
const start = cursor === null ? 0 : Math.max(0, all.findIndex(item => item.id === cursor) + 1);
|
|
21
|
+
const items = all.slice(start, start + limit);
|
|
22
|
+
return { items, nextCursor: start + limit < all.length ? items.at(-1).id : null };
|
|
23
|
+
}
|
|
24
|
+
get(sessionId) {
|
|
25
|
+
const session = this.requireSession(sessionId);
|
|
26
|
+
const { messages, tools } = projectSession(session);
|
|
27
|
+
return {
|
|
28
|
+
session: this.summary(session),
|
|
29
|
+
workspace: this.workspaces.get(session),
|
|
30
|
+
messages,
|
|
31
|
+
tools,
|
|
32
|
+
pendingPermissions: this.pending.snapshot(sessionId),
|
|
33
|
+
snapshotSeq: this.sequencer.currentSeq(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
workspace(sessionId) {
|
|
37
|
+
return this.workspaces.get(sessionId === undefined ? undefined : this.requireSession(sessionId));
|
|
38
|
+
}
|
|
39
|
+
summary(session) {
|
|
40
|
+
const agent = this.agents.get(session.id);
|
|
41
|
+
const title = this.titles?.get(session)?.title ?? fallbackTitle(session);
|
|
42
|
+
return {
|
|
43
|
+
id: String(session.id),
|
|
44
|
+
title,
|
|
45
|
+
...(session.header.cwd === undefined ? {} : { cwd: session.header.cwd }),
|
|
46
|
+
status: agent === undefined ? 'unavailable' : agent.status,
|
|
47
|
+
createdAt: session.header.createdAt,
|
|
48
|
+
updatedAt: session.events.at(-1)?.time ?? session.header.createdAt,
|
|
49
|
+
lastSeq: this.sequencer.currentSeq(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
mapEvent(session, event) {
|
|
53
|
+
const sessionId = String(session.id);
|
|
54
|
+
const raw = event;
|
|
55
|
+
switch (raw.type) {
|
|
56
|
+
case 'user/message':
|
|
57
|
+
return [mapped('message.created', sessionId, remoteMessage(raw.data, sessionId, raw.time))];
|
|
58
|
+
case 'assistant/chunk':
|
|
59
|
+
return this.mapChunk(sessionId, raw);
|
|
60
|
+
case 'assistant/message':
|
|
61
|
+
return this.mapAssistantMessage(sessionId, raw);
|
|
62
|
+
case 'tool/call': {
|
|
63
|
+
const tool = runningTool(raw, sessionId);
|
|
64
|
+
return [mapped('tool.started', sessionId, tool)];
|
|
65
|
+
}
|
|
66
|
+
case 'tool/result': {
|
|
67
|
+
const tool = finishedTool(raw, session);
|
|
68
|
+
return [mapped('tool.finished', sessionId, tool)];
|
|
69
|
+
}
|
|
70
|
+
default:
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
mapChunk(sessionId, event) {
|
|
75
|
+
const chunk = event.data.chunk;
|
|
76
|
+
if (chunk?.type !== 'text-delta' && chunk?.type !== 'reasoning-delta')
|
|
77
|
+
return [];
|
|
78
|
+
const streamId = assistantStreamId(sessionId, event.data.turn, event.data.step);
|
|
79
|
+
const state = this.streams.get(streamId) ?? { deltaIndex: 0, started: false };
|
|
80
|
+
const events = [];
|
|
81
|
+
if (!state.started) {
|
|
82
|
+
events.push(mapped('message.created', sessionId, {
|
|
83
|
+
id: streamId, messageId: streamId, sessionId, role: 'assistant', content: [], text: '', status: 'streaming', createdAt: event.time,
|
|
84
|
+
}));
|
|
85
|
+
state.started = true;
|
|
86
|
+
}
|
|
87
|
+
events.push(mapped('message.delta', sessionId, {
|
|
88
|
+
sessionId,
|
|
89
|
+
messageId: streamId,
|
|
90
|
+
deltaIndex: state.deltaIndex++,
|
|
91
|
+
delta: typeof chunk.text === 'string' ? chunk.text : '',
|
|
92
|
+
contentType: chunk.type === 'reasoning-delta' ? 'reasoning' : 'text',
|
|
93
|
+
final: false,
|
|
94
|
+
finishReason: null,
|
|
95
|
+
}));
|
|
96
|
+
this.streams.set(streamId, state);
|
|
97
|
+
return events;
|
|
98
|
+
}
|
|
99
|
+
mapAssistantMessage(sessionId, event) {
|
|
100
|
+
const streamId = assistantStreamId(sessionId, event.data.turn, event.data.step);
|
|
101
|
+
const state = this.streams.get(streamId);
|
|
102
|
+
this.streams.delete(streamId);
|
|
103
|
+
if (state === undefined) {
|
|
104
|
+
return [mapped('message.created', sessionId, remoteMessage(event.data.message, sessionId, event.time, streamId))];
|
|
105
|
+
}
|
|
106
|
+
return [mapped('message.delta', sessionId, {
|
|
107
|
+
sessionId,
|
|
108
|
+
messageId: streamId,
|
|
109
|
+
deltaIndex: state.deltaIndex,
|
|
110
|
+
delta: '',
|
|
111
|
+
final: true,
|
|
112
|
+
finishReason: null,
|
|
113
|
+
})];
|
|
114
|
+
}
|
|
115
|
+
requireSession(sessionId) {
|
|
116
|
+
const session = this.sessions.get(SessionId(sessionId));
|
|
117
|
+
if (session === undefined)
|
|
118
|
+
throw new SessionAdapterError('SESSION_NOT_FOUND', 'The session is no longer available.');
|
|
119
|
+
return session;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export class SessionAdapterError extends Error {
|
|
123
|
+
code;
|
|
124
|
+
constructor(code, message) {
|
|
125
|
+
super(message);
|
|
126
|
+
this.code = code;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function projectSession(session) {
|
|
130
|
+
const messages = [];
|
|
131
|
+
const tools = new Map();
|
|
132
|
+
for (const event of session.events) {
|
|
133
|
+
const raw = event;
|
|
134
|
+
if (raw.type === 'user/message')
|
|
135
|
+
messages.push(remoteMessage(raw.data, String(session.id), raw.time));
|
|
136
|
+
if (raw.type === 'assistant/message') {
|
|
137
|
+
messages.push(remoteMessage(raw.data.message, String(session.id), raw.time, assistantStreamId(String(session.id), raw.data.turn, raw.data.step)));
|
|
138
|
+
}
|
|
139
|
+
if (raw.type === 'tool/call')
|
|
140
|
+
tools.set(String(raw.data.callId), runningTool(raw, String(session.id)));
|
|
141
|
+
if (raw.type === 'tool/result')
|
|
142
|
+
tools.set(toolResultCallId(raw), finishedTool(raw, session));
|
|
143
|
+
}
|
|
144
|
+
return { messages, tools: [...tools.values()] };
|
|
145
|
+
}
|
|
146
|
+
function remoteMessage(message, sessionId, createdAt, idOverride) {
|
|
147
|
+
const content = Array.isArray(message.content) ? structuredClone(message.content) : [];
|
|
148
|
+
const id = idOverride ?? String(message.id);
|
|
149
|
+
return {
|
|
150
|
+
id,
|
|
151
|
+
messageId: id,
|
|
152
|
+
sessionId,
|
|
153
|
+
role: message.role === 'assistant' || message.role === 'system' ? message.role : 'user',
|
|
154
|
+
content,
|
|
155
|
+
text: textOf(content),
|
|
156
|
+
status: 'complete',
|
|
157
|
+
createdAt,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function runningTool(event, sessionId) {
|
|
161
|
+
const callId = String(event.data.callId);
|
|
162
|
+
return {
|
|
163
|
+
callId,
|
|
164
|
+
toolCallId: callId,
|
|
165
|
+
sessionId,
|
|
166
|
+
toolName: String(event.data.name),
|
|
167
|
+
title: String(event.data.name),
|
|
168
|
+
status: 'running',
|
|
169
|
+
input: parseJson(event.data.arguments),
|
|
170
|
+
output: null,
|
|
171
|
+
isError: false,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function finishedTool(event, session) {
|
|
175
|
+
const callId = toolResultCallId(event);
|
|
176
|
+
const started = [...session.events].reverse().find(candidate => candidate.type === 'tool/call' && String(candidate.data.callId) === callId);
|
|
177
|
+
const block = event.data.message?.content?.[0];
|
|
178
|
+
const isError = Boolean(block?.isError || event.data.error);
|
|
179
|
+
return {
|
|
180
|
+
callId,
|
|
181
|
+
toolCallId: callId,
|
|
182
|
+
sessionId: String(session.id),
|
|
183
|
+
toolName: String(started?.data?.name ?? 'tool'),
|
|
184
|
+
title: String(started?.data?.name ?? 'Tool'),
|
|
185
|
+
status: isError ? 'error' : 'success',
|
|
186
|
+
input: parseJson(started?.data?.arguments),
|
|
187
|
+
output: structuredClone(block?.content ?? event.data.message?.content ?? null),
|
|
188
|
+
isError,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function toolResultCallId(event) {
|
|
192
|
+
return String(event.data.message?.source?.callId ?? event.data.message?.content?.[0]?.toolCallId ?? 'unknown');
|
|
193
|
+
}
|
|
194
|
+
function assistantStreamId(sessionId, turn, step) {
|
|
195
|
+
return `assistant:${sessionId}:${String(turn)}:${String(step)}`;
|
|
196
|
+
}
|
|
197
|
+
function textOf(content) {
|
|
198
|
+
return content.flatMap((block) => {
|
|
199
|
+
if (typeof block !== 'object' || block === null)
|
|
200
|
+
return [];
|
|
201
|
+
const record = block;
|
|
202
|
+
if ((record.type === 'text' || record.type === 'reasoning') && typeof record.text === 'string')
|
|
203
|
+
return [record.text];
|
|
204
|
+
return [];
|
|
205
|
+
}).join('');
|
|
206
|
+
}
|
|
207
|
+
function parseJson(value) {
|
|
208
|
+
if (typeof value !== 'string')
|
|
209
|
+
return value ?? null;
|
|
210
|
+
try {
|
|
211
|
+
return JSON.parse(value);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function fallbackTitle(session) {
|
|
218
|
+
for (const event of [...session.events].reverse()) {
|
|
219
|
+
const raw = event;
|
|
220
|
+
if (raw.type === 'session/title' && typeof raw.data.title === 'string')
|
|
221
|
+
return raw.data.title;
|
|
222
|
+
}
|
|
223
|
+
const firstUser = session.events.find(event => event.type === 'user/message');
|
|
224
|
+
const text = textOf(Array.isArray(firstUser?.data?.content) ? firstUser.data.content : []).trim();
|
|
225
|
+
return text === '' ? String(session.id) : `${text.slice(0, 57)}${text.length > 57 ? '…' : ''}`;
|
|
226
|
+
}
|
|
227
|
+
function mapped(event, sessionId, data) {
|
|
228
|
+
return { event, sessionId, data };
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=session-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-adapter.js","sourceRoot":"","sources":["../../src/adapters/session-adapter.ts"],"names":[],"mappings":"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"}
|