@lemoncat7/dsh-partner 0.1.0-alpha.13
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 +79 -0
- package/cordis.patch.yml +9 -0
- package/lib/agent-runtime.d.ts +42 -0
- package/lib/agent-runtime.d.ts.map +1 -0
- package/lib/agent-runtime.js +203 -0
- package/lib/agent-runtime.js.map +1 -0
- package/lib/api.d.ts +28 -0
- package/lib/api.d.ts.map +1 -0
- package/lib/api.js +196 -0
- package/lib/api.js.map +1 -0
- package/lib/channels/manager.d.ts +28 -0
- package/lib/channels/manager.d.ts.map +1 -0
- package/lib/channels/manager.js +205 -0
- package/lib/channels/manager.js.map +1 -0
- package/lib/channels/weixin/api.d.ts +15 -0
- package/lib/channels/weixin/api.d.ts.map +1 -0
- package/lib/channels/weixin/api.js +86 -0
- package/lib/channels/weixin/api.js.map +1 -0
- package/lib/channels/weixin/login.d.ts +24 -0
- package/lib/channels/weixin/login.d.ts.map +1 -0
- package/lib/channels/weixin/login.js +71 -0
- package/lib/channels/weixin/login.js.map +1 -0
- package/lib/channels/weixin/types.d.ts +40 -0
- package/lib/channels/weixin/types.d.ts.map +1 -0
- package/lib/channels/weixin/types.js +2 -0
- package/lib/channels/weixin/types.js.map +1 -0
- package/lib/client-api.d.ts +69 -0
- package/lib/client-api.d.ts.map +1 -0
- package/lib/client-api.js +20 -0
- package/lib/client-api.js.map +1 -0
- package/lib/client.d.ts +4 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +1916 -0
- package/lib/client.js.map +7 -0
- package/lib/config.d.ts +11 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +27 -0
- package/lib/config.js.map +1 -0
- package/lib/credentials.d.ts +14 -0
- package/lib/credentials.d.ts.map +1 -0
- package/lib/credentials.js +28 -0
- package/lib/credentials.js.map +1 -0
- package/lib/domain.d.ts +71 -0
- package/lib/domain.d.ts.map +1 -0
- package/lib/domain.js +57 -0
- package/lib/domain.js.map +1 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +46 -0
- package/lib/index.js.map +1 -0
- package/lib/sidebar-anchor.d.ts +3 -0
- package/lib/sidebar-anchor.d.ts.map +1 -0
- package/lib/sidebar-anchor.js +38 -0
- package/lib/sidebar-anchor.js.map +1 -0
- package/lib/store.d.ts +12 -0
- package/lib/store.d.ts.map +1 -0
- package/lib/store.js +101 -0
- package/lib/store.js.map +1 -0
- package/package.json +111 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lemoncat7
|
|
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,79 @@
|
|
|
1
|
+
# DSH Partner
|
|
2
|
+
|
|
3
|
+
面向 DeepSeek Harness 的长期 AI 伙伴与微信渠道插件。
|
|
4
|
+
|
|
5
|
+
伙伴不是一次会话中的临时提示词。每个伙伴拥有独立身份、Agent Preset、模型路由、能力声明,以及按微信联系人隔离的 DSH Session。第一版以微信为主要渠道,使用腾讯微信 iLink Bot API,不模拟个人微信网页版协议。
|
|
6
|
+
|
|
7
|
+
## 当前能力
|
|
8
|
+
|
|
9
|
+
- 伙伴创建、编辑与删除
|
|
10
|
+
- Agent scoped 身份提示,仅影响该伙伴创建的 Agent
|
|
11
|
+
- 为伙伴选择 Agent Preset、提供方与模型
|
|
12
|
+
- 微信 iLink Bot 扫码连接
|
|
13
|
+
- `bot_token` 只保存到 DSH Credential Store,管理 API 和浏览器均不返回
|
|
14
|
+
- 微信渠道启用、停用、断线退避与运行状态
|
|
15
|
+
- 私聊首次联系配对审批
|
|
16
|
+
- `微信机器人 + 联系人` 独立 Session 路由
|
|
17
|
+
- DSH Agent 完整回复后回发微信,并保留 iLink `context_token`
|
|
18
|
+
- 修改伙伴身份或能力时清理该伙伴的渠道 Session,防止新旧人格串联
|
|
19
|
+
- Windows、macOS、Linux 兼容的原子状态写入
|
|
20
|
+
|
|
21
|
+
图片、文件、群聊策略和多渠道适配尚未开放。收到媒体消息时第一版只提供安全的占位说明,不会假装已经读取附件。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
dsh plugin --profile web add @lemoncat7/dsh-partner
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
本地压缩包:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dsh plugin --profile web add ./lemoncat7-dsh-partner-0.1.0-alpha.2.tgz
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
重启对应 DSH profile 后,左侧「空间」上方会出现「伙伴」。打开伙伴面板,创建或选择伙伴,再进入「微信」扫码。
|
|
36
|
+
|
|
37
|
+
## 默认配置
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
- insert:
|
|
41
|
+
- id: partner
|
|
42
|
+
name: '@lemoncat7/dsh-partner'
|
|
43
|
+
config:
|
|
44
|
+
statePath: !!js dshHomePath('partner/state.json')
|
|
45
|
+
exposeWeb: true
|
|
46
|
+
apiPrefix: /partner-local/v1
|
|
47
|
+
defaultCwd: ''
|
|
48
|
+
autoStartChannels: true
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`defaultCwd` 为空时使用 DSH 进程当前工作目录,以兼容桌面端和 Docker。可按部署情况显式设为真实存在的绝对路径。
|
|
52
|
+
|
|
53
|
+
## 微信流程
|
|
54
|
+
|
|
55
|
+
1. 插件请求 `/ilink/bot/get_bot_qrcode?bot_type=3`。
|
|
56
|
+
2. 页面每两秒检查二维码状态,确认后凭据直接进入 Credential Store。
|
|
57
|
+
3. 后台通过 `/ilink/bot/getupdates` 长轮询接收消息。
|
|
58
|
+
4. 未授权联系人只会创建配对请求。
|
|
59
|
+
5. 批准后,为该联系人创建或恢复独立 DSH Agent。
|
|
60
|
+
6. Agent 使用伙伴身份和所选 Preset 运行,最终文本通过 `/ilink/bot/sendmessage` 返回微信。
|
|
61
|
+
|
|
62
|
+
渠道身份只决定消息归属,不授予任何工具权限。SSH、知识库和未来 Git 插件仍执行各自的挂载、授权和审批规则。
|
|
63
|
+
|
|
64
|
+
## 数据与安全
|
|
65
|
+
|
|
66
|
+
- 普通状态:`statePath` 指向的 JSON 文件。
|
|
67
|
+
- 敏感凭据:DSH Credential Store,scope 为 `dsh-partner-weixin`。
|
|
68
|
+
- 管理 API:默认 `/partner-local/v1`,仅接受同源请求;写操作还要求 `X-DSH-Partner-Request: 1`。
|
|
69
|
+
- 微信机器人只能绑定一个伙伴;联系人上下文不会跨机器人、伙伴或其他联系人共享。
|
|
70
|
+
|
|
71
|
+
## 开发
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm install
|
|
75
|
+
npm test
|
|
76
|
+
npm pack --dry-run
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
要求 Node.js `^22.19.0 || >=24.0.0`,与当前 DSH 运行时一致。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { AgentDefaultModelConfig } from '@deepseek-ai/dsh-agent-default-model';
|
|
3
|
+
import type { AgentPresets } from '@deepseek-ai/dsh-agent-presets';
|
|
4
|
+
import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
5
|
+
import type { WorkspaceRegistry } from '@deepseek-ai/dsh-workspace';
|
|
6
|
+
import type { Companion, ChannelSession } from './domain.js';
|
|
7
|
+
import { PartnerStore } from './store.js';
|
|
8
|
+
type RuntimeContext = Context & {
|
|
9
|
+
agents: Context['agents'];
|
|
10
|
+
agentDefaultModel: AgentDefaultModelConfig;
|
|
11
|
+
agentPresets: AgentPresets;
|
|
12
|
+
workspaceRegistry: WorkspaceRegistry;
|
|
13
|
+
};
|
|
14
|
+
export declare class PartnerAgentRuntime {
|
|
15
|
+
private readonly ctx;
|
|
16
|
+
private readonly store;
|
|
17
|
+
private readonly defaultCwd;
|
|
18
|
+
private readonly handles;
|
|
19
|
+
private readonly queues;
|
|
20
|
+
private readonly workspaces;
|
|
21
|
+
constructor(ctx: RuntimeContext, store: PartnerStore, defaultCwd: string);
|
|
22
|
+
reply(companion: Companion, channelId: string, userId: string, text: string): Promise<string>;
|
|
23
|
+
prepareSession(routeId: string): Promise<ChannelSession>;
|
|
24
|
+
resetCompanion(companionId: string): Promise<void>;
|
|
25
|
+
reloadCompanion(companionId: string): Promise<void>;
|
|
26
|
+
private releaseCompanion;
|
|
27
|
+
resetChannel(channelId: string): Promise<void>;
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
private drive;
|
|
30
|
+
private ensureSession;
|
|
31
|
+
private ensureAgent;
|
|
32
|
+
private attachSession;
|
|
33
|
+
}
|
|
34
|
+
export declare function resolveAgentOptions(defaultModel: AgentDefaultModelConfig, companion: Companion): {
|
|
35
|
+
model: string;
|
|
36
|
+
provider: string;
|
|
37
|
+
reasoningEffort?: import("@deepseek-ai/dsh-llm").ReasoningEffortId;
|
|
38
|
+
};
|
|
39
|
+
export declare function canReuseSession(route: ChannelSession, companionId: string, archivedSessionIds: readonly SessionId[]): boolean;
|
|
40
|
+
export declare function partnerCwd(root: string, companionId: string): string;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=agent-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runtime.d.ts","sourceRoot":"","sources":["../src/agent-runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,KAAK,cAAc,GAAG,OAAO,GAAG;IAC9B,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACzB,iBAAiB,EAAE,uBAAuB,CAAA;IAC1C,YAAY,EAAE,YAAY,CAAA;IAC1B,iBAAiB,EAAE,iBAAiB,CAAA;CACrC,CAAA;AAED,qBAAa,mBAAmB;IAM5B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAP7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwC;gBAGhD,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,YAAY,EACnB,UAAU,EAAE,MAAM;IAG/B,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS7F,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IASxD,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI3C,gBAAgB;IASxB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAKd,KAAK;YAmBL,aAAa;YAoBb,WAAW;YA6CX,aAAa;CAS5B;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,uBAAuB,EAAE,SAAS,EAAE,SAAS;;;;EAM9F;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAE7H;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpE"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
5
|
+
export class PartnerAgentRuntime {
|
|
6
|
+
ctx;
|
|
7
|
+
store;
|
|
8
|
+
defaultCwd;
|
|
9
|
+
handles = new Map();
|
|
10
|
+
queues = new Map();
|
|
11
|
+
workspaces = new Map();
|
|
12
|
+
constructor(ctx, store, defaultCwd) {
|
|
13
|
+
this.ctx = ctx;
|
|
14
|
+
this.store = store;
|
|
15
|
+
this.defaultCwd = defaultCwd;
|
|
16
|
+
}
|
|
17
|
+
async reply(companion, channelId, userId, text) {
|
|
18
|
+
const key = `${channelId}:${userId}`;
|
|
19
|
+
const previous = this.queues.get(key) ?? Promise.resolve();
|
|
20
|
+
let output = '';
|
|
21
|
+
const current = previous.catch(() => { }).then(async () => { output = await this.drive(companion, channelId, userId, text); });
|
|
22
|
+
this.queues.set(key, current);
|
|
23
|
+
try {
|
|
24
|
+
await current;
|
|
25
|
+
return output;
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
if (this.queues.get(key) === current)
|
|
29
|
+
this.queues.delete(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async prepareSession(routeId) {
|
|
33
|
+
const route = this.store.snapshot().sessions.find(item => item.id === routeId);
|
|
34
|
+
if (route === undefined)
|
|
35
|
+
throw new Error('伙伴会话不存在');
|
|
36
|
+
const companion = this.store.snapshot().companions.find(item => item.id === route.companionId);
|
|
37
|
+
if (companion === undefined)
|
|
38
|
+
throw new Error('伙伴身份不存在');
|
|
39
|
+
await this.ensureAgent(companion, route);
|
|
40
|
+
return route;
|
|
41
|
+
}
|
|
42
|
+
async resetCompanion(companionId) {
|
|
43
|
+
await this.releaseCompanion(companionId);
|
|
44
|
+
await this.store.update(state => { state.sessions = state.sessions.filter(item => item.companionId !== companionId); });
|
|
45
|
+
}
|
|
46
|
+
async reloadCompanion(companionId) {
|
|
47
|
+
await this.releaseCompanion(companionId);
|
|
48
|
+
}
|
|
49
|
+
async releaseCompanion(companionId) {
|
|
50
|
+
const sessions = this.store.snapshot().sessions.filter(item => item.companionId === companionId);
|
|
51
|
+
await Promise.all(sessions.map(async (item) => {
|
|
52
|
+
const handle = this.handles.get(item.sessionId);
|
|
53
|
+
this.handles.delete(item.sessionId);
|
|
54
|
+
await handle?.dispose().catch(() => { });
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
async resetChannel(channelId) {
|
|
58
|
+
const sessions = this.store.snapshot().sessions.filter(item => item.channelId === channelId);
|
|
59
|
+
await Promise.all(sessions.map(async (item) => {
|
|
60
|
+
const handle = this.handles.get(item.sessionId);
|
|
61
|
+
this.handles.delete(item.sessionId);
|
|
62
|
+
await handle?.dispose().catch(() => { });
|
|
63
|
+
}));
|
|
64
|
+
await this.store.update(state => { state.sessions = state.sessions.filter(item => item.channelId !== channelId); });
|
|
65
|
+
}
|
|
66
|
+
async close() {
|
|
67
|
+
await Promise.all([...this.handles.values()].map(handle => handle.dispose().catch(() => { })));
|
|
68
|
+
this.handles.clear();
|
|
69
|
+
}
|
|
70
|
+
async drive(companion, channelId, userId, text) {
|
|
71
|
+
const session = await this.ensureSession(companion, channelId, userId);
|
|
72
|
+
const agent = await this.ensureAgent(companion, session);
|
|
73
|
+
if (agent.status !== 'idle')
|
|
74
|
+
await agent.whenIdle();
|
|
75
|
+
const startSeq = agent.session.seq;
|
|
76
|
+
agent.followup(createUserMessage({
|
|
77
|
+
content: [{ type: 'text', text }],
|
|
78
|
+
source: { kind: 'user' },
|
|
79
|
+
}));
|
|
80
|
+
await agent.whenIdle();
|
|
81
|
+
const response = extractAssistantText(agent, startSeq);
|
|
82
|
+
await this.store.update(state => {
|
|
83
|
+
const target = state.sessions.find(item => item.id === session.id);
|
|
84
|
+
if (target)
|
|
85
|
+
target.lastMessageAt = Date.now();
|
|
86
|
+
});
|
|
87
|
+
if (!response)
|
|
88
|
+
throw new Error('伙伴没有生成可发送的文本回复');
|
|
89
|
+
return response;
|
|
90
|
+
}
|
|
91
|
+
async ensureSession(companion, channelId, userId) {
|
|
92
|
+
const existing = this.store.snapshot().sessions.find(item => item.channelId === channelId && item.userId === userId);
|
|
93
|
+
if (existing !== undefined && canReuseSession(existing, companion.id, this.ctx.workspaceRegistry.archivedSessionIds))
|
|
94
|
+
return existing;
|
|
95
|
+
const now = Date.now();
|
|
96
|
+
const session = {
|
|
97
|
+
id: `route-${randomUUID()}`,
|
|
98
|
+
channelId,
|
|
99
|
+
userId,
|
|
100
|
+
companionId: companion.id,
|
|
101
|
+
sessionId: `session-${randomUUID()}`,
|
|
102
|
+
cwd: partnerCwd(this.defaultCwd, companion.id),
|
|
103
|
+
lastMessageAt: now,
|
|
104
|
+
};
|
|
105
|
+
await this.store.update(state => {
|
|
106
|
+
state.sessions = state.sessions.filter(item => !(item.channelId === channelId && item.userId === userId));
|
|
107
|
+
state.sessions.push(session);
|
|
108
|
+
});
|
|
109
|
+
return session;
|
|
110
|
+
}
|
|
111
|
+
async ensureAgent(companion, route) {
|
|
112
|
+
const cwd = route.cwd ?? this.defaultCwd;
|
|
113
|
+
await mkdir(cwd, { recursive: true, mode: 0o700 });
|
|
114
|
+
const held = this.handles.get(route.sessionId);
|
|
115
|
+
if (held !== undefined) {
|
|
116
|
+
await this.attachSession(companion, route);
|
|
117
|
+
return held.agent;
|
|
118
|
+
}
|
|
119
|
+
const live = this.ctx.agents.get(route.sessionId);
|
|
120
|
+
if (live !== undefined) {
|
|
121
|
+
await this.attachSession(companion, route);
|
|
122
|
+
return live;
|
|
123
|
+
}
|
|
124
|
+
const options = resolveAgentOptions(this.ctx.agentDefaultModel, companion);
|
|
125
|
+
const setup = async (agentCtx) => {
|
|
126
|
+
await this.ctx.agentPresets.mount(agentCtx, companion.presetId);
|
|
127
|
+
agentCtx.systemPrompt.section({
|
|
128
|
+
name: 'partner-identity',
|
|
129
|
+
order: -10,
|
|
130
|
+
text: renderPersona(companion),
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
let handle;
|
|
134
|
+
try {
|
|
135
|
+
handle = await this.ctx.agents.resume({
|
|
136
|
+
resumeSessionId: route.sessionId,
|
|
137
|
+
agentOptions: options,
|
|
138
|
+
setup,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
handle = await this.ctx.agents.create({
|
|
143
|
+
sessionId: route.sessionId,
|
|
144
|
+
meta: {
|
|
145
|
+
cwd,
|
|
146
|
+
...(companion.presetId ? { agentPreset: companion.presetId } : {}),
|
|
147
|
+
},
|
|
148
|
+
agentOptions: options,
|
|
149
|
+
setup,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
this.handles.set(route.sessionId, handle);
|
|
153
|
+
await this.attachSession(companion, route);
|
|
154
|
+
return handle.agent;
|
|
155
|
+
}
|
|
156
|
+
async attachSession(companion, route) {
|
|
157
|
+
const cwd = route.cwd ?? this.defaultCwd;
|
|
158
|
+
let workspace = this.workspaces.get(cwd);
|
|
159
|
+
if (workspace === undefined) {
|
|
160
|
+
workspace = this.ctx.workspaceRegistry.create(cwd, route.cwd === undefined ? '伙伴' : `伙伴 · ${companion.name}`);
|
|
161
|
+
this.workspaces.set(cwd, workspace);
|
|
162
|
+
}
|
|
163
|
+
await (await workspace).attachSession(route.sessionId);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export function resolveAgentOptions(defaultModel, companion) {
|
|
167
|
+
return {
|
|
168
|
+
...defaultModel.currentSelection(),
|
|
169
|
+
...(companion.provider ? { provider: companion.provider } : {}),
|
|
170
|
+
...(companion.model ? { model: companion.model } : {}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export function canReuseSession(route, companionId, archivedSessionIds) {
|
|
174
|
+
return route.companionId === companionId && !archivedSessionIds.includes(route.sessionId);
|
|
175
|
+
}
|
|
176
|
+
export function partnerCwd(root, companionId) {
|
|
177
|
+
return join(root, 'partners', companionId);
|
|
178
|
+
}
|
|
179
|
+
function renderPersona(companion) {
|
|
180
|
+
const capabilities = companion.capabilities.length > 0 ? companion.capabilities.join('、') : '由当前 Agent Preset 提供的基础能力';
|
|
181
|
+
return [
|
|
182
|
+
`你当前以长期工作伙伴「${companion.name}」的身份工作。`,
|
|
183
|
+
`角色:${companion.role}`,
|
|
184
|
+
companion.description ? `定位:${companion.description}` : '',
|
|
185
|
+
companion.instructions ? `长期行为准则:\n${companion.instructions}` : '',
|
|
186
|
+
`用户为此伙伴启用的能力范围:${capabilities}。能力标识不等于授权;只能调用当前会话实际提供且已经通过权限校验的工具。`,
|
|
187
|
+
'这个会话由 DSH 网页与微信私聊渠道共同使用。保持同一上下文,不要假定每条消息都来自微信;渠道回传由适配器负责。回答兼顾网页与移动端阅读,执行外部操作前继续遵守工具自身的授权与审批边界。',
|
|
188
|
+
].filter(Boolean).join('\n\n');
|
|
189
|
+
}
|
|
190
|
+
function extractAssistantText(agent, fromSeq) {
|
|
191
|
+
const messages = [];
|
|
192
|
+
for (const event of agent.session.events) {
|
|
193
|
+
if (event.seq < fromSeq || event.type !== 'assistant/message' || event.data.interrupted)
|
|
194
|
+
continue;
|
|
195
|
+
const text = event.data.message.content
|
|
196
|
+
.filter((block) => block.type === 'text')
|
|
197
|
+
.map(block => block.text.trim()).filter(Boolean).join('\n');
|
|
198
|
+
if (text)
|
|
199
|
+
messages.push(text);
|
|
200
|
+
}
|
|
201
|
+
return messages.join('\n\n').trim();
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=agent-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../src/agent-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAKhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAaxD,MAAM,OAAO,mBAAmB;IAMX;IACA;IACA;IAPF,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAA;IACxC,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAA;IACzC,UAAU,GAAG,IAAI,GAAG,EAA8B,CAAA;IAEnE,YACmB,GAAmB,EACnB,KAAmB,EACnB,UAAkB;QAFlB,QAAG,GAAH,GAAG,CAAgB;QACnB,UAAK,GAAL,KAAK,CAAc;QACnB,eAAU,GAAV,UAAU,CAAQ;IAClC,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,SAAoB,EAAE,SAAiB,EAAE,MAAc,EAAE,IAAY;QAC/E,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,MAAM,EAAE,CAAA;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1D,IAAI,MAAM,GAAG,EAAE,CAAA;QACf,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,GAAG,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;QAC5H,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC7B,IAAI,CAAC;YAAC,MAAM,OAAO,CAAC;YAAC,OAAO,MAAM,CAAA;QAAC,CAAC;gBAAS,CAAC;YAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAAC,CAAC;IAChH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,CAAA;QAC9E,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAA;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,WAAW,CAAC,CAAA;QAC9F,IAAI,SAAS,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAA;QACvD,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QACxC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,WAAmB;QACtC,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QACxC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IACxH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,WAAmB;QACvC,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;IAC1C,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,WAAmB;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,KAAK,WAAW,CAAC,CAAA;QAChG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;YAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC/C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACnC,MAAM,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACzC,CAAC,CAAC,CAAC,CAAA;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,SAAiB;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;QAC5F,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE;YAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC/C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACnC,MAAM,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACzC,CAAC,CAAC,CAAC,CAAA;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IACpH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC7F,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,SAAoB,EAAE,SAAiB,EAAE,MAAc,EAAE,IAAY;QACvF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QACtE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QACxD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAA;QACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAA;QAClC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAC/B,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YACjC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;SACzB,CAAC,CAAC,CAAA;QACH,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACtD,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAA;YAClE,IAAI,MAAM;gBAAE,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC/C,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAChD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,SAAoB,EAAE,SAAiB,EAAE,MAAc;QACjF,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;QACpH,IAAI,QAAQ,KAAK,SAAS,IAAI,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,kBAAkB,CAAC;YAAE,OAAO,QAAQ,CAAA;QACrI,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,OAAO,GAAmB;YAC9B,EAAE,EAAE,SAAS,UAAU,EAAE,EAAE;YAC3B,SAAS;YACT,MAAM;YACN,WAAW,EAAE,SAAS,CAAC,EAAE;YACzB,SAAS,EAAE,WAAW,UAAU,EAAE,EAAE;YACpC,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC;YAC9C,aAAa,EAAE,GAAG;SACnB,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC9B,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAA;YACzG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC9B,CAAC,CAAC,CAAA;QACF,OAAO,OAAO,CAAA;IAChB,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,SAAoB,EAAE,KAAqB;QACnE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAA;QACxC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC9C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAC1C,OAAO,IAAI,CAAC,KAAK,CAAA;QACnB,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAsB,CAAC,CAAA;QAC9D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAC1C,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;QAC1E,MAAM,KAAK,GAAG,KAAK,EAAE,QAAiB,EAAiB,EAAE;YACvD,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAA;YAC/D,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC;gBAC5B,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,CAAC,EAAE;gBACV,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC;aAC/B,CAAC,CAAA;QACJ,CAAC,CAAA;QACD,IAAI,MAAmB,CAAA;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;gBACpC,eAAe,EAAE,KAAK,CAAC,SAAsB;gBAC7C,YAAY,EAAE,OAAO;gBACrB,KAAK;aACN,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;gBACpC,SAAS,EAAE,KAAK,CAAC,SAAsB;gBACvC,IAAI,EAAE;oBACJ,GAAG;oBACH,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACnE;gBACD,YAAY,EAAE,OAAO;gBACrB,KAAK;aACN,CAAC,CAAA;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QACzC,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAC1C,OAAO,MAAM,CAAC,KAAK,CAAA;IACrB,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,SAAoB,EAAE,KAAqB;QACrE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAA;QACxC,IAAI,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACxC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA;YAC7G,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QACrC,CAAC;QACD,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,SAAsB,CAAC,CAAA;IACrE,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAqC,EAAE,SAAoB;IAC7F,OAAO;QACL,GAAG,YAAY,CAAC,gBAAgB,EAAE;QAClC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,WAAmB,EAAE,kBAAwC;IAClH,OAAO,KAAK,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAsB,CAAC,CAAA;AACxG,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,WAAmB;IAC1D,OAAO,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAA;AAC5C,CAAC;AAED,SAAS,aAAa,CAAC,SAAoB;IACzC,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAA;IACtH,OAAO;QACL,cAAc,SAAS,CAAC,IAAI,SAAS;QACrC,MAAM,SAAS,CAAC,IAAI,EAAE;QACtB,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;QAC1D,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE;QAClE,iBAAiB,YAAY,sCAAsC;QACnE,gGAAgG;KACjG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAChC,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAY,EAAE,OAAe;IACzD,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,GAAG,GAAG,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW;YAAE,SAAQ;QACjG,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;aACpC,MAAM,CAAC,CAAC,KAAK,EAA2C,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;aACjF,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC7D,IAAI,IAAI;YAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;AACrC,CAAC"}
|
package/lib/api.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { AgentPresets } from '@deepseek-ai/dsh-agent-presets';
|
|
4
|
+
import { PartnerStore } from './store.js';
|
|
5
|
+
import { PartnerCredentialVault } from './credentials.js';
|
|
6
|
+
import { ChannelManager } from './channels/manager.js';
|
|
7
|
+
import { WeixinLoginManager } from './channels/weixin/login.js';
|
|
8
|
+
import { PartnerAgentRuntime } from './agent-runtime.js';
|
|
9
|
+
export interface WebServerLike {
|
|
10
|
+
register(route: {
|
|
11
|
+
kind: 'prefix';
|
|
12
|
+
path: string;
|
|
13
|
+
handler(req: IncomingMessage, res: ServerResponse): void | Promise<void>;
|
|
14
|
+
}): () => void;
|
|
15
|
+
}
|
|
16
|
+
interface ApiRuntime {
|
|
17
|
+
ctx: Context & {
|
|
18
|
+
agentPresets: AgentPresets;
|
|
19
|
+
};
|
|
20
|
+
store: PartnerStore;
|
|
21
|
+
credentials: PartnerCredentialVault;
|
|
22
|
+
channels: ChannelManager;
|
|
23
|
+
agents: PartnerAgentRuntime;
|
|
24
|
+
login: WeixinLoginManager;
|
|
25
|
+
}
|
|
26
|
+
export declare function registerPartnerApi(webServer: WebServerLike, prefix: string, runtime: ApiRuntime): () => void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=api.d.ts.map
|
package/lib/api.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAqB,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAIxD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAAG,MAAM,IAAI,CAAA;CACxI;AAED,UAAU,UAAU;IAClB,GAAG,EAAE,OAAO,GAAG;QAAE,YAAY,EAAE,YAAY,CAAA;KAAE,CAAA;IAC7C,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,sBAAsB,CAAA;IACnC,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,KAAK,EAAE,kBAAkB,CAAA;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,MAAM,IAAI,CAU5G"}
|
package/lib/api.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { normalizeCompanionDraft, object, text } from './domain.js';
|
|
3
|
+
import { requiredCompanion } from './channels/manager.js';
|
|
4
|
+
const MAX_BODY_BYTES = 1_048_576;
|
|
5
|
+
export function registerPartnerApi(webServer, prefix, runtime) {
|
|
6
|
+
return webServer.register({
|
|
7
|
+
kind: 'prefix', path: prefix,
|
|
8
|
+
handler: async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
assertSameOrigin(req);
|
|
11
|
+
await dispatch(req, res, prefix, runtime);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
sendError(res, error);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async function dispatch(req, res, prefix, runtime) {
|
|
20
|
+
const url = new URL(req.url ?? '/', 'http://partner.local');
|
|
21
|
+
const relative = url.pathname.slice(prefix.length).replace(/^\/+|\/+$/g, '');
|
|
22
|
+
const segments = relative ? relative.split('/').map(decodeURIComponent) : [];
|
|
23
|
+
const method = req.method ?? 'GET';
|
|
24
|
+
if (method === 'GET' && segments[0] === 'health')
|
|
25
|
+
return sendJson(res, 200, { ok: true, service: 'dsh-partner', schemaVersion: 1 });
|
|
26
|
+
if (method === 'GET' && segments.length === 0)
|
|
27
|
+
return sendJson(res, 200, await snapshot(runtime));
|
|
28
|
+
if (segments[0] === 'companions') {
|
|
29
|
+
if (method === 'POST' && segments.length === 1) {
|
|
30
|
+
mutation(req);
|
|
31
|
+
const body = await readObject(req);
|
|
32
|
+
const draft = normalizeCompanionDraft(body.companion);
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
const companion = { ...draft, id: createId('companion'), createdAt: now, updatedAt: now };
|
|
35
|
+
await runtime.store.update(state => { state.companions.push(companion); });
|
|
36
|
+
return sendJson(res, 201, companion);
|
|
37
|
+
}
|
|
38
|
+
const id = segments[1];
|
|
39
|
+
if (id !== undefined && method === 'PUT' && segments.length === 2) {
|
|
40
|
+
mutation(req);
|
|
41
|
+
const previous = requiredCompanion(runtime.store, id);
|
|
42
|
+
const draft = normalizeCompanionDraft((await readObject(req)).companion);
|
|
43
|
+
const next = { ...draft, id, createdAt: previous.createdAt, updatedAt: Date.now() };
|
|
44
|
+
await runtime.agents.reloadCompanion(id);
|
|
45
|
+
await runtime.store.update(state => { state.companions = state.companions.map(item => item.id === id ? next : item); });
|
|
46
|
+
return sendJson(res, 200, next);
|
|
47
|
+
}
|
|
48
|
+
if (id !== undefined && method === 'DELETE' && segments.length === 2) {
|
|
49
|
+
mutation(req);
|
|
50
|
+
requiredCompanion(runtime.store, id);
|
|
51
|
+
if (runtime.store.snapshot().channels.some(item => item.companionId === id))
|
|
52
|
+
throw httpError(409, '请先删除或换绑该伙伴的微信渠道');
|
|
53
|
+
if (runtime.store.snapshot().companions.length <= 1)
|
|
54
|
+
throw httpError(409, '至少保留一个伙伴');
|
|
55
|
+
await runtime.agents.resetCompanion(id);
|
|
56
|
+
await runtime.store.update(state => { state.companions = state.companions.filter(item => item.id !== id); });
|
|
57
|
+
return sendJson(res, 204, undefined);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (segments[0] === 'weixin' && segments[1] === 'login') {
|
|
61
|
+
if (method === 'POST' && segments.length === 2) {
|
|
62
|
+
mutation(req);
|
|
63
|
+
const companionId = text((await readObject(req)).companionId, 'companionId', 120);
|
|
64
|
+
requiredCompanion(runtime.store, companionId);
|
|
65
|
+
return sendJson(res, 201, await runtime.login.begin(companionId));
|
|
66
|
+
}
|
|
67
|
+
const loginId = segments[2];
|
|
68
|
+
if (method === 'GET' && loginId !== undefined && segments.length === 3) {
|
|
69
|
+
const login = await runtime.login.poll(loginId);
|
|
70
|
+
if (login.phase !== 'confirmed')
|
|
71
|
+
return sendJson(res, 200, { login });
|
|
72
|
+
const confirmed = runtime.login.consume(loginId);
|
|
73
|
+
const now = Date.now();
|
|
74
|
+
const channel = {
|
|
75
|
+
id: createId('weixin'), companionId: confirmed.companionId, accountId: confirmed.accountId,
|
|
76
|
+
name: `微信 · ${confirmed.accountId.slice(-6)}`, enabled: true, createdAt: now, updatedAt: now,
|
|
77
|
+
};
|
|
78
|
+
await runtime.credentials.write(channel.id, { botToken: confirmed.botToken, baseUrl: confirmed.baseUrl });
|
|
79
|
+
try {
|
|
80
|
+
await runtime.store.update(state => { state.channels.push(channel); });
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
await runtime.credentials.delete(channel.id).catch(() => { });
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
await runtime.channels.start(channel.id);
|
|
87
|
+
return sendJson(res, 200, { login, channel });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (segments[0] === 'channels') {
|
|
91
|
+
const id = segments[1];
|
|
92
|
+
if (id !== undefined && method === 'POST' && segments[2] === 'enabled' && segments.length === 3) {
|
|
93
|
+
mutation(req);
|
|
94
|
+
const body = await readObject(req);
|
|
95
|
+
if (typeof body.enabled !== 'boolean')
|
|
96
|
+
throw httpError(400, 'enabled must be boolean');
|
|
97
|
+
await runtime.channels.setEnabled(id, body.enabled);
|
|
98
|
+
return sendJson(res, 200, { ok: true });
|
|
99
|
+
}
|
|
100
|
+
if (id !== undefined && method === 'DELETE' && segments.length === 2) {
|
|
101
|
+
mutation(req);
|
|
102
|
+
await runtime.channels.delete(id);
|
|
103
|
+
return sendJson(res, 204, undefined);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (segments[0] === 'pairings') {
|
|
107
|
+
const id = segments[1];
|
|
108
|
+
if (id !== undefined && method === 'POST' && segments[2] === 'status' && segments.length === 3) {
|
|
109
|
+
mutation(req);
|
|
110
|
+
const status = text((await readObject(req)).status, 'status', 20);
|
|
111
|
+
if (status !== 'approved' && status !== 'blocked')
|
|
112
|
+
throw httpError(400, 'pairing status is invalid');
|
|
113
|
+
const pairing = runtime.store.snapshot().pairings.find(item => item.id === id);
|
|
114
|
+
if (pairing === undefined)
|
|
115
|
+
throw httpError(404, '配对请求不存在');
|
|
116
|
+
await runtime.store.update(state => {
|
|
117
|
+
const target = state.pairings.find(item => item.id === id);
|
|
118
|
+
if (target) {
|
|
119
|
+
target.status = status;
|
|
120
|
+
target.updatedAt = Date.now();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return sendJson(res, 200, { ok: true });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (segments[0] === 'sessions') {
|
|
127
|
+
const id = segments[1];
|
|
128
|
+
if (id !== undefined && method === 'POST' && segments[2] === 'prepare' && segments.length === 3) {
|
|
129
|
+
mutation(req);
|
|
130
|
+
const route = await runtime.agents.prepareSession(id);
|
|
131
|
+
return sendJson(res, 200, { sessionId: route.sessionId });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
throw httpError(404, 'Partner API route was not found');
|
|
135
|
+
}
|
|
136
|
+
async function snapshot(runtime) {
|
|
137
|
+
const state = runtime.store.snapshot();
|
|
138
|
+
const presets = await runtime.ctx.agentPresets.list().then(items => items.map(item => ({
|
|
139
|
+
id: item.id,
|
|
140
|
+
name: item.name ?? item.id,
|
|
141
|
+
...(item.broken ? { broken: item.broken } : {}),
|
|
142
|
+
}))).catch(() => []);
|
|
143
|
+
return { companions: state.companions, channels: await runtime.channels.views(), pairings: state.pairings, sessions: state.sessions, presets };
|
|
144
|
+
}
|
|
145
|
+
function createId(prefix) { return `${prefix}-${randomBytes(10).toString('hex')}`; }
|
|
146
|
+
function assertSameOrigin(req) {
|
|
147
|
+
const origin = req.headers.origin;
|
|
148
|
+
const host = req.headers.host;
|
|
149
|
+
if (origin !== undefined && host !== undefined && new URL(origin).host !== host)
|
|
150
|
+
throw httpError(403, 'cross-origin Partner API access is forbidden');
|
|
151
|
+
const site = req.headers['sec-fetch-site'];
|
|
152
|
+
if (site !== undefined && site !== 'same-origin' && site !== 'same-site' && site !== 'none')
|
|
153
|
+
throw httpError(403, 'cross-site Partner API access is forbidden');
|
|
154
|
+
}
|
|
155
|
+
function mutation(req) {
|
|
156
|
+
if (req.headers['x-dsh-partner-request'] !== '1')
|
|
157
|
+
throw httpError(403, 'missing Partner mutation request header');
|
|
158
|
+
}
|
|
159
|
+
async function readObject(req) {
|
|
160
|
+
let total = 0;
|
|
161
|
+
const chunks = [];
|
|
162
|
+
for await (const chunk of req) {
|
|
163
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
164
|
+
total += buffer.length;
|
|
165
|
+
if (total > MAX_BODY_BYTES)
|
|
166
|
+
throw httpError(413, 'request body is too large');
|
|
167
|
+
chunks.push(buffer);
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
return object(JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}'), 'request body');
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (error instanceof HttpError)
|
|
174
|
+
throw error;
|
|
175
|
+
throw httpError(400, error instanceof Error ? error.message : 'request body is invalid');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
class HttpError extends Error {
|
|
179
|
+
status;
|
|
180
|
+
constructor(status, message) {
|
|
181
|
+
super(message);
|
|
182
|
+
this.status = status;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function httpError(status, message) { return new HttpError(status, message); }
|
|
186
|
+
function sendError(res, error) {
|
|
187
|
+
const status = error instanceof HttpError ? error.status : 500;
|
|
188
|
+
sendJson(res, status, { error: error instanceof Error ? error.message : String(error) });
|
|
189
|
+
}
|
|
190
|
+
function sendJson(res, status, value) {
|
|
191
|
+
res.statusCode = status;
|
|
192
|
+
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
193
|
+
res.setHeader('cache-control', 'no-store');
|
|
194
|
+
res.end(status === 204 ? undefined : JSON.stringify(value));
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|