personal-bot 0.2.8 → 0.2.10
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/CONTEXT.md +40 -59
- package/README.md +70 -119
- package/README.zh-CN.md +73 -116
- package/docs/README.md +22 -19
- package/docs/agent-collaboration.md +10 -12
- package/docs/architecture-guidelines.md +2 -2
- package/docs/capability-design.md +4 -12
- package/docs/dsh.md +32 -96
- package/docs/file-storage.md +8 -5
- package/docs/history.md +5 -12
- package/docs/installation-design.md +56 -198
- package/docs/model-context.md +23 -37
- package/docs/model-instruction-guidelines.md +2 -2
- package/docs/release.md +5 -5
- package/docs/technical-design.md +16 -12
- package/docs/workspace-configuration.md +55 -0
- package/lib/client.js +28 -3
- package/lib/common/typebox.LICENSE +23 -0
- package/lib/common/typebox.js +4740 -0
- package/lib/dsh.js +0 -5
- package/lib/extension/dsh/command.js +15 -11
- package/lib/extension/dsh/history.js +1 -1
- package/lib/extension/dsh/management.d.ts +4 -0
- package/lib/extension/dsh/management.js +21 -6
- package/lib/extension/dsh/workspace.d.ts +7 -1
- package/lib/extension/dsh/workspace.js +68 -1
- package/lib/extension/setup-cli.js +1 -1
- package/lib/integrations/dsh/skills.d.ts +4 -0
- package/lib/integrations/dsh/skills.js +27 -0
- package/lib/model/history.d.ts +1 -0
- package/lib/model/workspace-config.d.ts +9 -0
- package/lib/model/workspace-config.js +1 -0
- package/lib/services/history/history-service.d.ts +1 -2
- package/lib/services/history/history-service.js +27 -40
- package/lib/services/workspace/workspace-config.d.ts +7 -0
- package/lib/services/workspace/workspace-config.js +50 -0
- package/lib/services/workspace/workspace-preparation.d.ts +1 -0
- package/lib/services/workspace/workspace-preparation.js +8 -0
- package/lib/storage/history-files.d.ts +5 -1
- package/lib/storage/history-files.js +68 -15
- package/lib/tools/agents/contract.js +1 -1
- package/lib/tools/agents/dsh-contract.js +1 -1
- package/lib/tools/history/contract.js +1 -1
- package/lib/tools/teams/contract.js +1 -1
- package/lib/ui/dsh/management.js +27 -3
- package/npm-shrinkwrap.json +10 -3
- package/package.json +102 -31
- package/python/README.md +6 -6
- package/resources/prompts/workspace.md +3 -3
- package/scripts/README.md +16 -15
- package/src/dsh.ts +0 -5
- package/src/extension/command.ts +25 -8
- package/src/extension/dsh/command.ts +13 -8
- package/src/extension/dsh/history.ts +2 -2
- package/src/extension/dsh/management.ts +21 -5
- package/src/extension/dsh/workspace.ts +62 -5
- package/src/extension/events.ts +18 -1
- package/src/extension/lifecycle.ts +9 -2
- package/src/extension/setup-cli.ts +1 -1
- package/src/extension/subagent-entry.ts +4 -1
- package/src/integrations/dsh/skills.ts +30 -0
- package/src/integrations/pi/skills.ts +52 -0
- package/src/model/history.ts +1 -0
- package/src/model/workspace-config.ts +10 -0
- package/src/pbot.ts +2 -3
- package/src/services/history/history-service.ts +15 -25
- package/src/services/workspace/workspace-config.ts +49 -0
- package/src/services/workspace/workspace-preparation.ts +8 -0
- package/src/storage/history-files.ts +53 -15
- package/src/ui/dsh/management.ts +20 -3
- package/docs/dsh-implementation-plan.md +0 -160
- package/docs/dsh-support-proposal.md +0 -298
- package/docs/dsh.en.md +0 -333
- package/docs/subagent-upgrade-proposal.md +0 -357
- package/docs/validation.md +0 -189
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readdirSync, rmdirSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { object } from "../common/json.js";
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, rmdirSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { canonical, object } from "../common/json.js";
|
|
4
4
|
import { requireThat } from "../common/validation.js";
|
|
5
|
-
import { readJsonFile, writeJsonFile } from "./atomic-json.js";
|
|
5
|
+
import { internalPath, readJsonFile, syncDirectory, writeJsonFile } from "./atomic-json.js";
|
|
6
6
|
import { fileId } from "./file-access.js";
|
|
7
7
|
const strings = (value) => Array.isArray(value) && value.every(item => typeof item === "string");
|
|
8
8
|
function record(value) {
|
|
9
|
-
requireThat(object(value) &&
|
|
9
|
+
requireThat(object(value) && (value.host === "pi" || value.host === "dsh") &&
|
|
10
|
+
typeof value.id === "string" && typeof value.sessionId === "string" &&
|
|
10
11
|
typeof value.name === "string" && Array.isArray(value.nodes), "历史索引无效。");
|
|
11
12
|
for (const node of value.nodes)
|
|
12
13
|
requireThat(object(node) && typeof node.id === "string" &&
|
|
@@ -21,25 +22,77 @@ function record(value) {
|
|
|
21
22
|
export class HistoryFiles {
|
|
22
23
|
directory;
|
|
23
24
|
host;
|
|
25
|
+
#warnings = [];
|
|
24
26
|
constructor(directory, host = "pi") {
|
|
25
27
|
this.directory = directory;
|
|
26
28
|
this.host = host;
|
|
27
29
|
}
|
|
28
|
-
|
|
30
|
+
get warnings() { return this.#warnings; }
|
|
31
|
+
list() {
|
|
32
|
+
this.#warnings = [];
|
|
29
33
|
if (!existsSync(this.directory))
|
|
30
34
|
return [];
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const records = [];
|
|
36
|
+
for (const name of readdirSync(this.directory).filter(name => name.endsWith(".json"))) {
|
|
37
|
+
try {
|
|
38
|
+
const value = readJsonFile(this.directory, name, record);
|
|
39
|
+
requireThat(name === fileId(value.id) + ".json", "历史文件名与根 ID 不匹配。");
|
|
40
|
+
if (value.host === this.host)
|
|
41
|
+
records.push(value);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
this.#warnings.push(join(this.directory, name) + ": " + String(error));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return records;
|
|
48
|
+
}
|
|
49
|
+
/** Publish each legacy archive with its directory's host before removing the old copy. */
|
|
50
|
+
migrate(root) {
|
|
51
|
+
const directory = join(root, "." + this.host, "pbot/history");
|
|
52
|
+
if (!existsSync(directory))
|
|
53
|
+
return;
|
|
54
|
+
this.control(() => {
|
|
55
|
+
if (!existsSync(directory))
|
|
56
|
+
return;
|
|
57
|
+
const legacyLock = join(directory, ".write");
|
|
58
|
+
mkdirSync(legacyLock, { mode: 0o700 });
|
|
59
|
+
try {
|
|
60
|
+
for (const name of readdirSync(directory).filter(name => name.endsWith(".json"))) {
|
|
61
|
+
const source = internalPath(directory, name), target = internalPath(this.directory, name);
|
|
62
|
+
requireThat(source !== target, "新旧历史目录指向同一位置。");
|
|
63
|
+
const value = readJsonFile(directory, name, value => {
|
|
64
|
+
requireThat(object(value) && (value.host === undefined || value.host === this.host), "旧历史归档与来源目录不匹配。");
|
|
65
|
+
return record({ ...value, host: this.host });
|
|
66
|
+
});
|
|
67
|
+
requireThat(name === fileId(value.id) + ".json", "历史文件名与根 ID 不匹配。");
|
|
68
|
+
if (!writeJsonFile(this.directory, name, value, record, true)) {
|
|
69
|
+
requireThat(canonical(readJsonFile(this.directory, name, record)) === canonical(value), "历史归档迁移冲突,请核对新旧文件:" + name);
|
|
70
|
+
}
|
|
71
|
+
syncDirectory(this.directory);
|
|
72
|
+
unlinkSync(source);
|
|
73
|
+
syncDirectory(directory);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
rmdirSync(legacyLock);
|
|
78
|
+
}
|
|
79
|
+
rmdirSync(directory);
|
|
80
|
+
const parent = dirname(directory);
|
|
81
|
+
syncDirectory(parent);
|
|
82
|
+
try {
|
|
83
|
+
rmdirSync(parent);
|
|
84
|
+
syncDirectory(dirname(parent));
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (!["ENOTEMPTY", "EEXIST"].includes(error.code ?? ""))
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
38
91
|
}
|
|
39
92
|
/** The callback is synchronous: no SDK reads or model work can hold this source's write lock. */
|
|
40
93
|
control(operation) {
|
|
41
94
|
mkdirSync(this.directory, { recursive: true, mode: 0o700 });
|
|
42
|
-
const lock = join(this.directory, ".write");
|
|
95
|
+
const lock = join(this.directory, ".write-" + this.host);
|
|
43
96
|
try {
|
|
44
97
|
mkdirSync(lock, { mode: 0o700 });
|
|
45
98
|
}
|
|
@@ -56,7 +109,7 @@ export class HistoryFiles {
|
|
|
56
109
|
}
|
|
57
110
|
}
|
|
58
111
|
save(value) {
|
|
59
|
-
requireThat(
|
|
112
|
+
requireThat(value.host === this.host, "历史归档与来源不匹配。");
|
|
60
113
|
mkdirSync(this.directory, { recursive: true, mode: 0o700 });
|
|
61
114
|
writeJsonFile(this.directory, fileId(value.id) + ".json", value, record);
|
|
62
115
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
1
|
+
import { Type } from "../../common/typebox.js";
|
|
2
2
|
export const agentDescription = "委派专家并继续对话。start 启动后即返回,完成自动通知,无需轮询;省略初始输入时待命。send 继续对话,团队占用期间不可私人 send。status 查看状态,read 读取报告;读取已结束周期即领取其通知,包括部分读取。续读固定 cycle.cycleId 并使用 nextOffset。state 表示执行状态,cycle.state 表示工作结果,queued 只表示入队。stop 保留历史,resume 携新 message 继续。每个父会话最多 50 个存活专家,空闲也计入。";
|
|
3
3
|
const id = Type.String({ minLength: 1, maxLength: 128 });
|
|
4
4
|
const message = Type.String({ minLength: 1, maxLength: 24000, description: "本次目标、相关资料、约束和交付要求。" });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
1
|
+
import { Type } from "../../common/typebox.js";
|
|
2
2
|
import { agentActionSchema, agentParametersSchema, agentStartOptions } from "./contract.js";
|
|
3
3
|
const options = Type.Omit(Type.Object(agentStartOptions), ["provider", "model", "thinking", "files", "tools", "noExtensions", "noPromptTemplates", "noContextFiles", "noSkills"]).properties;
|
|
4
4
|
const native = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
1
|
+
import { Type } from "../../common/typebox.js";
|
|
2
2
|
import { requireThat, schema } from "../../common/validation.js";
|
|
3
3
|
const host = Type.Union([Type.Literal("pi"), Type.Literal("dsh")]);
|
|
4
4
|
const nullableOffset = Type.Union([Type.Integer(), Type.Null()]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
1
|
+
import { Type } from "../../common/typebox.js";
|
|
2
2
|
export const teamDescription = "组织固定成员协作。create 建立团队,run 开始一批讨论。运行时占用成员;pause 停止新安排,允许在途工作收尾,之后可私人 send;中止成员用 pbot_agent stop。close 保留成员和历史;换成员须关闭旧团队再创建。继续讨论用 run 提交新要求。成员最终答复向团队公开。";
|
|
3
3
|
export const teamMessageDescription = "读写团队公共原文。post 向全体成员发布信息,需要安排回答时由主会话调用 pbot_team run;成员只能在自己的团队工作中 post。read 用 afterSeq 翻页,长正文按 seq/offset 续读,先补完 nextOffset 非空的消息。";
|
|
4
4
|
const id = Type.String({ minLength: 1, maxLength: 128 });
|
package/lib/ui/dsh/management.js
CHANGED
|
@@ -78,6 +78,8 @@ export function showManagement(ctx, parentSessionId) {
|
|
|
78
78
|
}
|
|
79
79
|
function form(parent) { const node = element("form"); parent.append(node); return node; }
|
|
80
80
|
function activate(id) {
|
|
81
|
+
if (snapshot?.enabled === false && id !== "status")
|
|
82
|
+
return;
|
|
81
83
|
tab = id;
|
|
82
84
|
for (const [key, section] of sections)
|
|
83
85
|
section.hidden = key !== id;
|
|
@@ -157,7 +159,7 @@ export function showManagement(ctx, parentSessionId) {
|
|
|
157
159
|
counts.classList.add("pbot-counts");
|
|
158
160
|
const materials = group(status, "pbot-setting");
|
|
159
161
|
materials.append(element("h3", "资料目录"));
|
|
160
|
-
button(materials, "准备目录", async () => { await command("init", undefined, "
|
|
162
|
+
const initializeButton = button(materials, "准备目录", async () => { await command("init", undefined, "工作区已初始化并启用。"); });
|
|
161
163
|
const pythonCard = group(status, "pbot-setting"), pythonInfo = group(pythonCard);
|
|
162
164
|
const pythonButton = button(pythonCard, "准备 Python", async () => { await command("python setup", undefined, "Python 准备完成。"); });
|
|
163
165
|
const diagnostic = details(status, "环境详情"), statusBody = block("");
|
|
@@ -625,13 +627,35 @@ export function showManagement(ctx, parentSessionId) {
|
|
|
625
627
|
return;
|
|
626
628
|
location.textContent = text(snapshot.workspaceRoot).split(/[\\/]/).filter(Boolean).at(-1) ?? "";
|
|
627
629
|
location.title = text(snapshot.workspaceRoot);
|
|
630
|
+
if (snapshot.enabled === false) {
|
|
631
|
+
const configuration = record(snapshot.configuration);
|
|
632
|
+
counts.textContent = configuration.error ? "Personal Bot 配置错误" : "Personal Bot 未启用";
|
|
633
|
+
workspaceInfo.replaceChildren(facts([["状态", configuration.error ? "配置错误" : "未启用"], ["工作区", snapshot.workspaceRoot], ["配置文件", configuration.path]]), note(configuration.error ? "修复配置文件后执行 /pbot init。" : "执行 /pbot init,或点击下方按钮初始化并启用。"));
|
|
634
|
+
pythonInfo.replaceChildren(note("启用工作区后自动准备共享 Python 环境。"));
|
|
635
|
+
materials.hidden = false;
|
|
636
|
+
initializeButton.textContent = "初始化并启用";
|
|
637
|
+
enabled(initializeButton, !configuration.error);
|
|
638
|
+
for (const [id, control] of tabs)
|
|
639
|
+
enabled(control, id === "status");
|
|
640
|
+
enabled(pythonButton, false);
|
|
641
|
+
activate("status");
|
|
642
|
+
statusBody.textContent = JSON.stringify(snapshot, null, 2);
|
|
643
|
+
if (configuration.error)
|
|
644
|
+
inform(text(configuration.error), "error");
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
for (const control of tabs.values())
|
|
648
|
+
enabled(control, true);
|
|
649
|
+
materials.hidden = false;
|
|
650
|
+
initializeButton.textContent = "准备目录";
|
|
651
|
+
enabled(initializeButton, true);
|
|
628
652
|
const agents = rows(snapshot.agents), teams = rows(snapshot.teams), python = record(snapshot.python), history = record(snapshot.history);
|
|
629
653
|
tabCounts.get("experts").textContent = text(agents.length);
|
|
630
654
|
tabCounts.get("teams").textContent = text(teams.length);
|
|
631
655
|
const active = agents.filter(agent => ["starting", "busy", "stopping"].includes(text(agent.state))).length;
|
|
632
|
-
counts.textContent =
|
|
656
|
+
counts.textContent = `Personal Bot 已启动 · 专家 ${agents.length} · 执行中 ${active} · 团队 ${teams.length}`;
|
|
633
657
|
const model = object(snapshot.model) ? snapshot.model : {};
|
|
634
|
-
workspaceInfo.replaceChildren(facts([["工作区", snapshot.workspaceRoot], ["模型", model.model || "尚未选择"], ["Provider", model.provider || "—"],
|
|
658
|
+
workspaceInfo.replaceChildren(facts([["状态", "已启动"], ["工作区", snapshot.workspaceRoot], ["配置文件", record(snapshot.configuration).path], ["模型", model.model || "尚未选择"], ["Provider", model.provider || "—"],
|
|
635
659
|
["历史", history.organizing ? "整理中" : history.pending === null ? "查询时更新索引" : `${history.pending} 项待整理`]]));
|
|
636
660
|
pythonInfo.replaceChildren(element("h3", "Python"), badge(python.state));
|
|
637
661
|
if (python.error)
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "personal-bot",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "personal-bot",
|
|
9
|
-
"version": "0.2.
|
|
9
|
+
"version": "0.2.10",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ajv": "8.17.1",
|
|
12
12
|
"ajv-formats": "3.0.1",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"@deepseek-ai/dsh-fs-patch": "0.2.2-rc.1",
|
|
30
30
|
"@deepseek-ai/dsh-home-paths": "0.2.2-rc.1",
|
|
31
31
|
"@deepseek-ai/dsh-llm": "0.2.2-rc.1",
|
|
32
|
+
"@deepseek-ai/dsh-scope": "0.2.2-rc.1",
|
|
32
33
|
"@deepseek-ai/dsh-session": "0.2.2-rc.1",
|
|
33
34
|
"@deepseek-ai/dsh-session-persistence": "0.2.2-rc.1",
|
|
34
35
|
"@deepseek-ai/dsh-session-query": "0.2.2-rc.1",
|
|
@@ -68,6 +69,7 @@
|
|
|
68
69
|
"@deepseek-ai/dsh-fs-patch": "*",
|
|
69
70
|
"@deepseek-ai/dsh-home-paths": "*",
|
|
70
71
|
"@deepseek-ai/dsh-llm": "*",
|
|
72
|
+
"@deepseek-ai/dsh-scope": "*",
|
|
71
73
|
"@deepseek-ai/dsh-session": "*",
|
|
72
74
|
"@deepseek-ai/dsh-session-persistence": "*",
|
|
73
75
|
"@deepseek-ai/dsh-session-query": "*",
|
|
@@ -122,6 +124,9 @@
|
|
|
122
124
|
"@deepseek-ai/dsh-llm": {
|
|
123
125
|
"optional": true
|
|
124
126
|
},
|
|
127
|
+
"@deepseek-ai/dsh-scope": {
|
|
128
|
+
"optional": true
|
|
129
|
+
},
|
|
125
130
|
"@deepseek-ai/dsh-session": {
|
|
126
131
|
"optional": true
|
|
127
132
|
},
|
|
@@ -166,6 +171,9 @@
|
|
|
166
171
|
},
|
|
167
172
|
"@earendil-works/pi-tui": {
|
|
168
173
|
"optional": true
|
|
174
|
+
},
|
|
175
|
+
"typebox": {
|
|
176
|
+
"optional": true
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
},
|
|
@@ -4684,7 +4692,6 @@
|
|
|
4684
4692
|
"integrity": "sha512-FOJbXYvrskIcrb/4eVMMQfp0kaReTSBtIry2KsGNURb0OJfelqeSKaB1MsQQq/sOxbt3nPJIN9HY00SwmrTk3Q==",
|
|
4685
4693
|
"dev": true,
|
|
4686
4694
|
"license": "MIT",
|
|
4687
|
-
"peer": true,
|
|
4688
4695
|
"peerDependencies": {
|
|
4689
4696
|
"@deepseek-ai/cordis": "~4.1.0"
|
|
4690
4697
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "personal-bot",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/realqiyan/personal-bot.git"
|
|
@@ -22,21 +22,36 @@
|
|
|
22
22
|
"extensions": [
|
|
23
23
|
"./src/pbot.ts"
|
|
24
24
|
],
|
|
25
|
-
"skills": [
|
|
25
|
+
"skills": [],
|
|
26
26
|
"prompts": [],
|
|
27
27
|
"themes": []
|
|
28
28
|
},
|
|
29
29
|
"dsh": {
|
|
30
|
-
"bundle": {
|
|
30
|
+
"bundle": {
|
|
31
|
+
"patch": "./resources/dsh/cordis.patch.yml"
|
|
32
|
+
},
|
|
31
33
|
"client": {
|
|
32
34
|
"platform": "web",
|
|
33
|
-
"inject": [
|
|
35
|
+
"inject": [
|
|
36
|
+
"@deepseek-ai/dsh-api-remotes",
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-commands",
|
|
38
|
+
"@deepseek-ai/dsh-client-file-upload"
|
|
39
|
+
]
|
|
34
40
|
}
|
|
35
41
|
},
|
|
36
42
|
"exports": {
|
|
37
|
-
".": {
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./lib/dsh.d.ts",
|
|
45
|
+
"default": "./lib/dsh.js"
|
|
46
|
+
},
|
|
47
|
+
"./dsh": {
|
|
48
|
+
"types": "./lib/dsh.d.ts",
|
|
49
|
+
"default": "./lib/dsh.js"
|
|
50
|
+
},
|
|
51
|
+
"./client": {
|
|
52
|
+
"types": "./lib/ui/dsh/index.d.ts",
|
|
53
|
+
"default": "./lib/client.js"
|
|
54
|
+
},
|
|
40
55
|
"./*": "./*"
|
|
41
56
|
},
|
|
42
57
|
"files": [
|
|
@@ -84,6 +99,7 @@
|
|
|
84
99
|
"@deepseek-ai/dsh-tools": "*",
|
|
85
100
|
"@deepseek-ai/dsh-home-paths": "*",
|
|
86
101
|
"@deepseek-ai/dsh-system-prompt": "*",
|
|
102
|
+
"@deepseek-ai/dsh-scope": "*",
|
|
87
103
|
"@deepseek-ai/dsh-skill": "*",
|
|
88
104
|
"@deepseek-ai/dsh-skill-filesystem": "*",
|
|
89
105
|
"@deepseek-ai/dsh-working-directory": "*",
|
|
@@ -100,30 +116,81 @@
|
|
|
100
116
|
"typebox": "*"
|
|
101
117
|
},
|
|
102
118
|
"peerDependenciesMeta": {
|
|
103
|
-
"@deepseek-ai/cordis": {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
"@deepseek-ai/dsh-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
"@deepseek-ai/dsh-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"@deepseek-ai/dsh-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"@deepseek-ai/dsh-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
"@deepseek-ai/dsh-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"@deepseek-ai/dsh-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"@deepseek-ai/dsh-
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
"@deepseek-ai/cordis": {
|
|
120
|
+
"optional": true
|
|
121
|
+
},
|
|
122
|
+
"@deepseek-ai/dsh-agent": {
|
|
123
|
+
"optional": true
|
|
124
|
+
},
|
|
125
|
+
"@deepseek-ai/dsh-agent-preset-registry": {
|
|
126
|
+
"optional": true
|
|
127
|
+
},
|
|
128
|
+
"@deepseek-ai/dsh-session": {
|
|
129
|
+
"optional": true
|
|
130
|
+
},
|
|
131
|
+
"@deepseek-ai/dsh-session-persistence": {
|
|
132
|
+
"optional": true
|
|
133
|
+
},
|
|
134
|
+
"@deepseek-ai/dsh-session-query": {
|
|
135
|
+
"optional": true
|
|
136
|
+
},
|
|
137
|
+
"@deepseek-ai/dsh-llm": {
|
|
138
|
+
"optional": true
|
|
139
|
+
},
|
|
140
|
+
"@deepseek-ai/dsh-commands": {
|
|
141
|
+
"optional": true
|
|
142
|
+
},
|
|
143
|
+
"@deepseek-ai/dsh-api-remotes": {
|
|
144
|
+
"optional": true
|
|
145
|
+
},
|
|
146
|
+
"@deepseek-ai/dsh-client-ui-commands": {
|
|
147
|
+
"optional": true
|
|
148
|
+
},
|
|
149
|
+
"@deepseek-ai/dsh-client-file-upload": {
|
|
150
|
+
"optional": true
|
|
151
|
+
},
|
|
152
|
+
"@deepseek-ai/dsh-tools": {
|
|
153
|
+
"optional": true
|
|
154
|
+
},
|
|
155
|
+
"@deepseek-ai/dsh-home-paths": {
|
|
156
|
+
"optional": true
|
|
157
|
+
},
|
|
158
|
+
"@deepseek-ai/dsh-system-prompt": {
|
|
159
|
+
"optional": true
|
|
160
|
+
},
|
|
161
|
+
"@deepseek-ai/dsh-scope": {
|
|
162
|
+
"optional": true
|
|
163
|
+
},
|
|
164
|
+
"@deepseek-ai/dsh-skill": {
|
|
165
|
+
"optional": true
|
|
166
|
+
},
|
|
167
|
+
"@deepseek-ai/dsh-skill-filesystem": {
|
|
168
|
+
"optional": true
|
|
169
|
+
},
|
|
170
|
+
"@deepseek-ai/dsh-working-directory": {
|
|
171
|
+
"optional": true
|
|
172
|
+
},
|
|
173
|
+
"@deepseek-ai/dsh-fs": {
|
|
174
|
+
"optional": true
|
|
175
|
+
},
|
|
176
|
+
"@deepseek-ai/dsh-attachment": {
|
|
177
|
+
"optional": true
|
|
178
|
+
},
|
|
179
|
+
"@deepseek-ai/dsh-fs-patch": {
|
|
180
|
+
"optional": true
|
|
181
|
+
},
|
|
182
|
+
"@deepseek-ai/dsh-user-approval": {
|
|
183
|
+
"optional": true
|
|
184
|
+
},
|
|
185
|
+
"@deepseek-ai/dsh-tool-executor-ptc": {
|
|
186
|
+
"optional": true
|
|
187
|
+
},
|
|
188
|
+
"@deepseek-ai/dsh-typert-protocol": {
|
|
189
|
+
"optional": true
|
|
190
|
+
},
|
|
191
|
+
"@deepseek-ai/dsh-typert-registry": {
|
|
192
|
+
"optional": true
|
|
193
|
+
},
|
|
127
194
|
"@earendil-works/pi-ai": {
|
|
128
195
|
"optional": true
|
|
129
196
|
},
|
|
@@ -132,6 +199,9 @@
|
|
|
132
199
|
},
|
|
133
200
|
"@earendil-works/pi-tui": {
|
|
134
201
|
"optional": true
|
|
202
|
+
},
|
|
203
|
+
"typebox": {
|
|
204
|
+
"optional": true
|
|
135
205
|
}
|
|
136
206
|
},
|
|
137
207
|
"dependencies": {
|
|
@@ -155,6 +225,7 @@
|
|
|
155
225
|
"@deepseek-ai/dsh-tools": "0.2.2-rc.1",
|
|
156
226
|
"@deepseek-ai/dsh-home-paths": "0.2.2-rc.1",
|
|
157
227
|
"@deepseek-ai/dsh-system-prompt": "0.2.2-rc.1",
|
|
228
|
+
"@deepseek-ai/dsh-scope": "0.2.2-rc.1",
|
|
158
229
|
"@deepseek-ai/dsh-skill": "0.2.2-rc.1",
|
|
159
230
|
"@deepseek-ai/dsh-skill-filesystem": "0.2.2-rc.1",
|
|
160
231
|
"@deepseek-ai/dsh-working-directory": "0.2.2-rc.1",
|
package/python/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 自动准备与激活
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
工作区的 `.pbot/config.json` 设置 `enabled: true` 后,Pi 加载或原生 `/reload` 时自动执行 setup;dsh 在首个已启用工作区加载时准备环境。无需另行确认或指定 Python 路径。同一系统用户的两种宿主共用该环境:
|
|
8
8
|
|
|
9
9
|
1. 共享 venv 不存在时创建,不使用系统 site-packages。
|
|
10
10
|
2. 按 `requirements.lock` 补齐或对齐依赖,允许升级或降级;已匹配时不重新安装。
|
|
@@ -18,11 +18,11 @@ Pi 加载 Personal Bot、原生 `/reload`,或 dsh 加载 pbot Host 组件时
|
|
|
18
18
|
|
|
19
19
|
首次准备从当前 PATH 选择 python3,无该命令时使用 python;需要 Python 3.11+ 和 venv/ensurepip。系统 Python 只用于创建独立 venv,不在系统环境中安装依赖。现有环境不自动替换基础解释器,也不删除额外安装的包。
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
首次安装可能需要数分钟和网络。`/pbot init` 创建共用启用配置并启动环境准备;手工设置 enabled 为 true 后重载也会准备环境。不需要 Personal Bot 的工作区可保留配置缺失或设置 enabled 为 false,再重载或重启宿主;也可通过宿主原生配置取消加载整个插件。`/pbot status` 显示环境状态。所属激活生命周期关闭时恢复本扩展修改的进程环境变量;dsh 按整个 pbot 组件共享激活,不随某个浏览器页面或单个工作区关闭而恢复,不覆盖期间其他代码对变量的新修改。外部终端和 shell 配置不变。
|
|
22
22
|
|
|
23
23
|
## 失败与手工重试
|
|
24
24
|
|
|
25
|
-
环境异常时提醒,并在状态中保留错误。pbot 的其他能力仍可使用,但不把 Python 标记为就绪,也不替模型自动换用系统 Python 执行研究。原生 Bash
|
|
25
|
+
环境异常时提醒,并在状态中保留错误。pbot 的其他能力仍可使用,但不把 Python 标记为就绪,也不替模型自动换用系统 Python 执行研究。原生 Bash 仍然可用。
|
|
26
26
|
|
|
27
27
|
检查错误后可执行:
|
|
28
28
|
|
|
@@ -34,7 +34,7 @@ Pi 加载 Personal Bot、原生 `/reload`,或 dsh 加载 pbot Host 组件时
|
|
|
34
34
|
|
|
35
35
|
安装只接受 wheel,不编译 C 库、不安装系统软件,不绕过系统 Python 的安装保护。没有匹配 wheel、网络不可用、权限不足或环境损坏时停止。TA-Lib wheel 包含底层库,但并非所有系统和架构都有匹配 wheel。pip 安装配置被忽略,避免包被重定向到其他目标。
|
|
36
36
|
|
|
37
|
-
多个 pbot 进程同时启动时,通过共享排他锁串行准备,后取得锁的进程重新检查。锁文件不删除。该锁不管理普通 Python
|
|
37
|
+
多个 pbot 进程同时启动时,通过共享排他锁串行准备,后取得锁的进程重新检查。锁文件不删除。该锁不管理普通 Python 进程;更换插件版本或手工重试前,应停止使用该环境的脚本。不同插件版本可能要求不同依赖,不宜同时使用。
|
|
38
38
|
|
|
39
39
|
## 独立准备
|
|
40
40
|
|
|
@@ -51,7 +51,7 @@ python3 scripts/setup-python.py --check # 只检查,不创建或安装
|
|
|
51
51
|
|
|
52
52
|
setup 安装 numpy、pandas、TA-Lib、backtesting、scipy、statsmodels、matplotlib、scikit-learn、pyarrow、openpyxl、seaborn 和 Bokeh。按任务导入,环境与项目运行见[计算参考](../resources/references/compute.md),需要技术指标或回测时再读[指标与回测](../resources/references/compute-finance.md)。市场规则、费用、成交时点和数据切分由具体研究确定,原生 Backtest 不自动提供 A 股 T+1、整手或涨跌停约束。
|
|
53
53
|
|
|
54
|
-
激活后直接执行 `python scripts/analyze.py` 或 `python -m analysis.main`。工作目录、模块导入、参数和结果位置遵循项目约定。项目构建或测试明确要求另一环境时,按项目约定执行。pbot 不复制源码、不生成输入文件或计算记录、不管理研究进程的超时。Python 与 Bash
|
|
54
|
+
激活后直接执行 `python scripts/analyze.py` 或 `python -m analysis.main`。工作目录、模块导入、参数和结果位置遵循项目约定。项目构建或测试明确要求另一环境时,按项目约定执行。pbot 不复制源码、不生成输入文件或计算记录、不管理研究进程的超时。Python 与 Bash 使用实际账户权限,操作范围见[工具与执行](../docs/capability-design.md)。
|
|
55
55
|
|
|
56
56
|
在已激活环境中验证:
|
|
57
57
|
|
|
@@ -60,7 +60,7 @@ python -m pip check
|
|
|
60
60
|
python -B -m unittest discover -s python/tests -v
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
Node
|
|
63
|
+
Node 测试检查环境探测、错误、取消与激活恢复,使用临时 venv 和原生 Bash。上述 Python 测试在已准备的环境中检查原生库配合与文件往返。
|
|
64
64
|
|
|
65
65
|
依赖版本独立于插件版本。更新锁文件须检查最低 Python 3.11 与目标环境的兼容性,不只按开发机选择最新版。
|
|
66
66
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## 资料与环境
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
沿用已有工作区约定;新资料按下列用途组织。文档按主题维护当前说明,保留读者理解、决策和操作所需的信息。正文维护一份,其他位置用引用连接。
|
|
14
14
|
|
|
15
15
|
| 路径 | 用途 |
|
|
16
16
|
| --- | --- |
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
| `agents/` | `coordinator.md`、`general-purpose.md` 的职责补充 |
|
|
24
24
|
| `.agents/skills/` | 工作区自有专业方法 |
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
保存有后续用途的结论、方法、决策和产物;普通问答不逐轮存档。保存前查找同主题正文,直接修订,合并重复内容并替换过时说明。必要的实现细节放入对应技术资料,排查过程和测试流水不逐次追加到正文。更新或整理时使用 project-maintenance。可再次查询的数据按记录的口径获取。保留用户资料、历史记录和备份。
|
|
27
27
|
|
|
28
28
|
环境上下文中的 `workspaceRoot` 是资料工作区根目录,`resourceRoot` 是包内资料根目录,`python` 给出共享环境状态。资料路径相对工作区根目录,命令与文件工具按实际 cwd 解析路径。需要 Python 时读取包内 `references/compute.md`;共享环境未就绪时不退回系统 Python。项目构建和测试遵循项目声明的环境。
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
答复先给结论,按需补充说明和产物路径。自然语言说明直接回答当前问题,不惯常追加否定式限定或免责声明,也不设想用户未提出的推论再逐一否定。必要的未知、条件和风险清楚说明一次。数值注明影响理解的对象、期间、单位与口径。任务要求、操作权限、必要确认和规定的输出格式照常遵循。
|
package/scripts/README.md
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
# 维护脚本
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 构建
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
| 命令 | 作用 |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `npm run build` | 清理 dist,编译测试模块,再构建 CLI 与 dsh 产物 |
|
|
8
|
+
| `npm run build:cli` | 清理 lib,编译独立安装器、Pi 检查桥接与启动保护 |
|
|
9
|
+
| `npm run build:dsh` | 编译 Host,将 TypeBox 与许可证纳入 lib,再构建原生 Web Loader 模块 |
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
完整构建与 prepack 先构建 CLI,再构建 dsh。宿主 SDK 保持 external;dsh 编译模块引用包内 TypeBox,原模块位置保留。Pi 扩展由宿主直接加载 src。
|
|
8
12
|
|
|
9
|
-
##
|
|
13
|
+
## 安装包检查
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
先运行 `npm pack`,再将生成的 tarball 路径传给检查脚本:
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
| 命令 | 检查内容 | 环境 |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `node scripts/check-consumer.mjs <tarball>` | 独立 CLI、Pi 扩展、技能、工具与资料初始化 | CI 使用 Node.js 22.19.0,脚本安装锁定的 Pi SDK |
|
|
20
|
+
| `node scripts/check-dsh-consumer.mjs <tarball>` | dsh 原生插件安装、独立 CLI 与 Host 导入;检查无需单独安装 TypeBox 或宿主 SDK | Node.js 24.9+、仓库开发依赖和 PATH 中的 pnpm |
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
脚本使用隔离的用户目录、宿主配置与工作目录,完成后清理临时目录。两项检查均不调用模型;Pi 使用预置故障目录跳过 Python 依赖下载,dsh 通过原生 schema 收集导入 Host。
|
|
16
23
|
|
|
17
|
-
##
|
|
24
|
+
## Python 准备
|
|
18
25
|
|
|
19
|
-
`
|
|
20
|
-
|
|
21
|
-
## 构建清理
|
|
22
|
-
|
|
23
|
-
`clean-dist.mjs` 由 npm run build 调用,仅清理仓库内生成的 dist/,供 TypeScript 重新编译测试导入。
|
|
24
|
-
|
|
25
|
-
本包不提供工作区升级命令或历史转换脚本。插件安装和更新由对应宿主的原生包管理或用户维护的源码目录负责。
|
|
26
|
+
`setup-python.py` 按 `python/requirements.lock` 准备用户共享 venv。Personal Bot 加载时自动调用,也可运行独立脚本或 `/pbot python setup`。路径、依赖与排障见 [Python 说明](../python/README.md)。
|
package/src/dsh.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
1
|
import type { Context } from "@deepseek-ai/cordis";
|
|
3
|
-
import * as SkillFilesystem from "@deepseek-ai/dsh-skill-filesystem";
|
|
4
|
-
import { resourceRoot } from "./common/paths.js";
|
|
5
2
|
import { registerDshCommand } from "./extension/dsh/command.js";
|
|
6
3
|
import { registerDshManagement } from "./extension/dsh/management.js";
|
|
7
4
|
import { DshWorkspaces, dshDependencies } from "./extension/dsh/workspace.js";
|
|
@@ -13,7 +10,6 @@ export const inject = ["commands", "typert", ...dshDependencies];
|
|
|
13
10
|
export async function apply(ctx: Context) {
|
|
14
11
|
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
15
12
|
requireThat(major! > 24 || (major === 24 && minor! >= 9), "dsh 接入需要 Node.js 24.9.0 或更新版本。");
|
|
16
|
-
await ctx.plugin(SkillFilesystem, { providerName: "pbot", includeDefaultRoots: false, bundledSkillDir: join(resourceRoot, "skills") });
|
|
17
13
|
const workspaces = new DshWorkspaces(ctx);
|
|
18
14
|
ctx.effect(() => () => workspaces.close());
|
|
19
15
|
const management = registerDshManagement(ctx, workspaces);
|
|
@@ -22,5 +18,4 @@ export async function apply(ctx: Context) {
|
|
|
22
18
|
if (ctx.agents.roots().includes(agent) && agent.session.header.origin !== "subagent") await workspaces.open(agent);
|
|
23
19
|
});
|
|
24
20
|
for (const agent of ctx.agents.roots()) if (agent.session.header.origin !== "subagent") await workspaces.open(agent);
|
|
25
|
-
void workspaces.preparePython().catch(error => ctx.logger.warn(String(error)));
|
|
26
21
|
}
|