@zihanw/pi-forge 0.4.0-beta.1 → 0.4.0
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/CHANGELOG.md +37 -1
- package/PUBLIC_API.md +3 -26
- package/README.md +90 -601
- package/README.zh-CN.md +86 -585
- package/SUBAGENT_ADAPTER_CONTRACT.md +3 -197
- package/dist/forge-config.d.ts +80 -0
- package/dist/forge-config.d.ts.map +1 -1
- package/dist/forge-config.js +268 -18
- package/dist/forge-config.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.js +1 -1
- package/dist/profile-service.d.ts +1 -1
- package/dist/profile-service.d.ts.map +1 -1
- package/dist/profile-service.js +10 -5
- package/dist/profile-service.js.map +1 -1
- package/dist/runtime/subagent-runtime.d.ts +23 -8
- package/dist/runtime/subagent-runtime.d.ts.map +1 -1
- package/dist/runtime/subagent-runtime.js +283 -62
- package/dist/runtime/subagent-runtime.js.map +1 -1
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +15 -1
- package/dist/storage.js.map +1 -1
- package/dist/subagent/canonical.d.ts +19 -7
- package/dist/subagent/canonical.d.ts.map +1 -1
- package/dist/subagent/canonical.js +19 -47
- package/dist/subagent/canonical.js.map +1 -1
- package/dist/subagent/contract.d.ts +1 -2
- package/dist/subagent/contract.d.ts.map +1 -1
- package/dist/subagent/contract.js +1 -2
- package/dist/subagent/contract.js.map +1 -1
- package/dist/subagent/index.d.ts +4 -3
- package/dist/subagent/index.d.ts.map +1 -1
- package/dist/subagent/index.js +4 -3
- package/dist/subagent/index.js.map +1 -1
- package/dist/subagent/plan.d.ts +5 -1
- package/dist/subagent/plan.d.ts.map +1 -1
- package/dist/subagent/plan.js +28 -31
- package/dist/subagent/plan.js.map +1 -1
- package/dist/subagent/types.d.ts +62 -178
- package/dist/subagent/types.d.ts.map +1 -1
- package/dist/subagent/types.js +1 -1
- package/dist/subagent/types.js.map +1 -1
- package/dist/subagent/validation.d.ts +14 -14
- package/dist/subagent/validation.d.ts.map +1 -1
- package/dist/subagent/validation.js +52 -238
- package/dist/subagent/validation.js.map +1 -1
- package/dist/subagent-command.d.ts.map +1 -1
- package/dist/subagent-command.js +109 -16
- package/dist/subagent-command.js.map +1 -1
- package/dist/subagent-host.d.ts.map +1 -1
- package/dist/subagent-host.js +1 -0
- package/dist/subagent-host.js.map +1 -1
- package/dist/subagent-profile-tool.d.ts +25 -2
- package/dist/subagent-profile-tool.d.ts.map +1 -1
- package/dist/subagent-profile-tool.js +39 -8
- package/dist/subagent-profile-tool.js.map +1 -1
- package/dist/subagent-tool.d.ts +6 -3
- package/dist/subagent-tool.d.ts.map +1 -1
- package/dist/subagent-tool.js +85 -14
- package/dist/subagent-tool.js.map +1 -1
- package/dist/web-editor/client-script.generated.d.ts +1 -1
- package/dist/web-editor/client-script.generated.d.ts.map +1 -1
- package/dist/web-editor/client-script.generated.js +1 -1
- package/dist/web-editor/client-script.generated.js.map +1 -1
- package/dist/web-editor/client-styles.d.ts +2 -0
- package/dist/web-editor/client-styles.d.ts.map +1 -0
- package/dist/web-editor/client-styles.generated.d.ts +2 -0
- package/dist/web-editor/client-styles.generated.d.ts.map +1 -0
- package/dist/web-editor/client-styles.generated.js +3 -0
- package/dist/web-editor/client-styles.generated.js.map +1 -0
- package/dist/web-editor/client-styles.js +2 -0
- package/dist/web-editor/client-styles.js.map +1 -0
- package/dist/web-editor/page.d.ts +2 -0
- package/dist/web-editor/page.d.ts.map +1 -1
- package/dist/web-editor/page.js +11 -73
- package/dist/web-editor/page.js.map +1 -1
- package/dist/web-editor/server.d.ts.map +1 -1
- package/dist/web-editor/server.js +148 -0
- package/dist/web-editor/server.js.map +1 -1
- package/dist/web-editor/styles.d.ts.map +1 -1
- package/dist/web-editor/styles.js +60 -3
- package/dist/web-editor/styles.js.map +1 -1
- package/dist/web-editor/types.d.ts +79 -0
- package/dist/web-editor/types.d.ts.map +1 -1
- package/dist/web-host.d.ts +13 -2
- package/dist/web-host.d.ts.map +1 -1
- package/dist/web-host.js +301 -0
- package/dist/web-host.js.map +1 -1
- package/docs/README.md +41 -0
- package/docs/concepts/agent-profiles.md +60 -0
- package/docs/concepts/prompt-stacks.md +90 -0
- package/docs/design/README.md +17 -0
- package/docs/design/roadmap-0.4-archive.md +216 -0
- package/docs/design/subagents/design-review.md +220 -0
- package/docs/design/subagents/interface-design.md +274 -0
- package/docs/design/subagents/sdk-spike-findings.md +117 -0
- package/docs/development/complexity-review.md +86 -0
- package/docs/development/release.md +31 -0
- package/docs/development/roadmap.md +42 -0
- package/docs/development/setup.md +75 -0
- package/docs/getting-started.md +93 -0
- package/docs/guides/custom-macros-and-slots.md +68 -0
- package/docs/guides/debugging.md +39 -0
- package/docs/guides/delegation.md +99 -0
- package/docs/guides/sillytavern-import.md +47 -0
- package/docs/guides/use-cases.md +65 -0
- package/docs/guides/web-editor.md +75 -0
- package/docs/reference/commands.md +60 -0
- package/docs/reference/configuration.md +64 -0
- package/docs/reference/features.md +279 -0
- package/docs/reference/macros-and-slots.md +82 -0
- package/docs/reference/public-api.md +28 -0
- package/docs/reference/stack-schema.md +167 -0
- package/docs/reference/subagent-adapter.md +204 -0
- package/docs/zh-CN/README.md +37 -0
- package/docs/zh-CN/concepts/agent-profiles.md +44 -0
- package/docs/zh-CN/concepts/prompt-stacks.md +40 -0
- package/docs/zh-CN/getting-started.md +79 -0
- package/docs/zh-CN/guides/delegation.md +66 -0
- package/docs/zh-CN/guides/web-editor.md +45 -0
- package/docs/zh-CN/reference/commands.md +58 -0
- package/package.json +28 -14
- package/dist/subagent/backend-registry.d.ts +0 -75
- package/dist/subagent/backend-registry.d.ts.map +0 -1
- package/dist/subagent/backend-registry.js +0 -463
- package/dist/subagent/backend-registry.js.map +0 -1
- package/dist/subagent/diagnostics.d.ts +0 -3
- package/dist/subagent/diagnostics.d.ts.map +0 -1
- package/dist/subagent/diagnostics.js +0 -5
- package/dist/subagent/diagnostics.js.map +0 -1
- package/dist/subagent/pi-model-runtime.d.ts +0 -8
- package/dist/subagent/pi-model-runtime.d.ts.map +0 -1
- package/dist/subagent/pi-model-runtime.js +0 -22
- package/dist/subagent/pi-model-runtime.js.map +0 -1
- package/dist/subagent/pi-sdk-backend.d.ts +0 -23
- package/dist/subagent/pi-sdk-backend.d.ts.map +0 -1
- package/dist/subagent/pi-sdk-backend.js +0 -383
- package/dist/subagent/pi-sdk-backend.js.map +0 -1
- package/dist/subagent/pi-subprocess-backend.d.ts +0 -72
- package/dist/subagent/pi-subprocess-backend.d.ts.map +0 -1
- package/dist/subagent/pi-subprocess-backend.js +0 -756
- package/dist/subagent/pi-subprocess-backend.js.map +0 -1
- package/dist/subagent/subprocess-bridge.d.ts +0 -21
- package/dist/subagent/subprocess-bridge.d.ts.map +0 -1
- package/dist/subagent/subprocess-bridge.js +0 -87
- package/dist/subagent/subprocess-bridge.js.map +0 -1
- package/dist/subagent/subprocess-report.d.ts +0 -4
- package/dist/subagent/subprocess-report.d.ts.map +0 -1
- package/dist/subagent/subprocess-report.js +0 -55
- package/dist/subagent/subprocess-report.js.map +0 -1
- package/dist/subagent-contract.d.ts +0 -8
- package/dist/subagent-contract.d.ts.map +0 -1
- package/dist/subagent-contract.js +0 -8
- package/dist/subagent-contract.js.map +0 -1
- package/dist/web-editor/client/api.d.ts +0 -9
- package/dist/web-editor/client/api.d.ts.map +0 -1
- package/dist/web-editor/client/api.js +0 -26
- package/dist/web-editor/client/api.js.map +0 -1
- package/dist/web-editor/client/dom.d.ts +0 -13
- package/dist/web-editor/client/dom.d.ts.map +0 -1
- package/dist/web-editor/client/dom.js +0 -30
- package/dist/web-editor/client/dom.js.map +0 -1
- package/dist/web-editor/client/inspector.d.ts +0 -22
- package/dist/web-editor/client/inspector.d.ts.map +0 -1
- package/dist/web-editor/client/inspector.js +0 -226
- package/dist/web-editor/client/inspector.js.map +0 -1
- package/dist/web-editor/client/main.d.ts +0 -2
- package/dist/web-editor/client/main.d.ts.map +0 -1
- package/dist/web-editor/client/main.js +0 -1468
- package/dist/web-editor/client/main.js.map +0 -1
- package/dist/web-editor/client/policy-editor.d.ts +0 -16
- package/dist/web-editor/client/policy-editor.d.ts.map +0 -1
- package/dist/web-editor/client/policy-editor.js +0 -330
- package/dist/web-editor/client/policy-editor.js.map +0 -1
- package/dist/web-editor/client/regex-editor.d.ts +0 -19
- package/dist/web-editor/client/regex-editor.d.ts.map +0 -1
- package/dist/web-editor/client/regex-editor.js +0 -281
- package/dist/web-editor/client/regex-editor.js.map +0 -1
- package/dist/web-editor/client/types.d.ts +0 -60
- package/dist/web-editor/client/types.d.ts.map +0 -1
- package/dist/web-editor/client/types.js +0 -2
- package/dist/web-editor/client/types.js.map +0 -1
package/README.zh-CN.md
CHANGED
|
@@ -1,649 +1,150 @@
|
|
|
1
1
|
# pi-forge
|
|
2
2
|
|
|
3
|
-
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
3
|
+
[English](README.md) | [简体中文](README.zh-CN.md) · [中文文档](docs/zh-CN/README.md)
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
**pi-forge** 让你自定义 Pi
|
|
7
|
+
**pi-forge** 让你自定义 [Pi](https://github.com/badlogic/pi-mono) 的思考方式和行为。Prompt stack(提示栈)负责 prompt 组合和工具策略;agent profile(agent 配置预设)可以一次性应用模型、思考等级和提示栈。
|
|
8
8
|
|
|
9
|
-
可以把它理解为 AI agent
|
|
9
|
+
可以把它理解为 AI agent 的角色卡和工作台。
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## 主要能力
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
13
|
+
- 把 system prompt、聊天历史、工具、skills、项目上下文和运行时数据组合成可排序的 block 和 slot。
|
|
14
|
+
- 用一条命令切换编程、审查、写作、角色扮演和翻译模式。
|
|
15
|
+
- 保存并应用完整的模型/思考等级/提示栈预设。
|
|
16
|
+
- 按栈严格限制工具,并过滤模型可见的 skills。
|
|
17
|
+
- 使用静态、轮次和会话变量,以及支持嵌套的模板宏。
|
|
18
|
+
- 对发给模型的 prompt 或最终 assistant 消息执行确定性 regex 转换。
|
|
19
|
+
- 导入 SillyTavern 预设并检查迁移报告。
|
|
20
|
+
- 在本地 Web 编辑器中管理 stack/profile,并检查实际 provider payload。
|
|
21
|
+
- 用明确启用的 profile 运行实验性、需要审批的前台 subagent。
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## 安装
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
pi-forge 需要 Node.js 22.19 或更高版本。
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
pi install npm:@zihanw/pi-forge
|
|
28
|
+
pi install npm:@zihanw/pi-forge
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
安装或更新后请重启 Pi。运行中的 Pi host 会向 extension 提供 SDK package;pi-forge 只在开发和测试中固定精确版本,以保证结果可复现,不会用 peer dependency 锁死 Pi 频繁发布的版本。兼容策略见[开发与兼容性](docs/development/setup.md#pi-compatibility)(英文)。
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
## 五分钟上手
|
|
34
34
|
|
|
35
|
-
###
|
|
35
|
+
### 1. 创建 prompt stack
|
|
36
36
|
|
|
37
|
-
从 [
|
|
38
|
-
|
|
39
|
-
默认示例参考了 `@earendil-works/pi-coding-agent/dist/core/system-prompt.js` 中 Pi 自己的 prompt builder,但把它拆成可移动的 pi-forge slot:角色、工具、guidelines、Pi 文档提示、append-system-prompt、项目上下文、技能、日期/cwd 和对话历史。
|
|
37
|
+
从 [默认 Pi mirror](examples/default-prompt-stack.json) 创建 `.pi/forge/prompt-stacks/default.json`:
|
|
40
38
|
|
|
41
39
|
```bash
|
|
42
40
|
mkdir -p .pi/forge/prompt-stacks
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
把示例 JSON 粘贴进去。如果你就在这个仓库里开发,也可以直接执行 `cp examples/default-prompt-stack.json .pi/forge/prompt-stacks/default.json`。
|
|
47
|
-
|
|
48
|
-
搞定。重启 Pi 或执行 `/preset reload`。如果当前没有选中其他栈,`default.json` 会自动启用;如果你之前执行过 `/preset use none` 或选择了别的栈,请执行 `/preset use default`。
|
|
49
|
-
|
|
50
|
-
### 可视化编辑器
|
|
51
|
-
|
|
52
|
-
不想手写 JSON?pi-forge 内置了 Web 编辑器:
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
/preset ui
|
|
41
|
+
cp examples/default-prompt-stack.json .pi/forge/prompt-stacks/default.json
|
|
56
42
|
```
|
|
57
43
|
|
|
58
|
-
|
|
44
|
+
如果你通过 npm 安装而不是 clone 仓库,请直接打开 `/preset ui` 新建 stack;编辑器使用相同的 Pi mirror 布局。
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
编辑器默认运行在一个可用的 `127.0.0.1` 端口,并带有会话 token,所以多个 Pi 实例可以同时打开各自的编辑器。如果 Pi 在 session navigation 或新会话后重新初始化扩展,同一项目中的 `/preset ui` 会复用已有编辑器 URL,不会遗留旧 server 后再开一个新端口;resources 和 preview 在生命周期刷新后仍可使用。写入需要项目被信任,且只会写入 prompt-stack 存储目录。新建的栈会写入 `.pi/forge/prompt-stacks`;旧的 `.pi/prompt-stacks` 栈仍然可读取和编辑。保存、导入、fork、删除成功后会重新加载到当前 Pi 会话。需要时可以用 `/preset ui restart` 或 `/preset ui stop`。
|
|
63
|
-
|
|
64
|
-
要把旧栈复制到新位置,执行 `/preset migrate-stacks`。加 `--dry-run` 可先预览,加 `--overwrite` 可覆盖目标文件,加 `--delete-legacy` 会在复制成功后删除旧文件。
|
|
65
|
-
|
|
66
|
-
如果想优先使用某个端口,可以创建 `.pi/forge/config.json`。如果该端口被占用,pi-forge 会回退到其他可用端口,并显示实际 URL:
|
|
67
|
-
|
|
68
|
-
```json
|
|
69
|
-
{
|
|
70
|
-
"webEditor": {
|
|
71
|
-
"port": 41738
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Agent profile
|
|
77
|
-
|
|
78
|
-
Agent profile 是保存在 `.pi/forge/agent-profiles` 下的项目级 JSON 文件。先正常配置 Pi,然后捕获当前模型、思考等级和 prompt stack,就能快速创建:
|
|
46
|
+
重启 Pi,或执行:
|
|
79
47
|
|
|
80
48
|
```text
|
|
81
|
-
/
|
|
82
|
-
/
|
|
49
|
+
/preset reload
|
|
50
|
+
/preset use default
|
|
83
51
|
```
|
|
84
52
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
也可以直接编写 profile:
|
|
88
|
-
|
|
89
|
-
```json
|
|
90
|
-
{
|
|
91
|
-
"schemaVersion": 1,
|
|
92
|
-
"type": "pi-forge.agent-profile",
|
|
93
|
-
"id": "reviewer",
|
|
94
|
-
"name": "Reviewer",
|
|
95
|
-
"description": "只审查代码,不做修改。",
|
|
96
|
-
"autoActivate": true,
|
|
97
|
-
"model": {
|
|
98
|
-
"provider": "provider-id",
|
|
99
|
-
"id": "model-id"
|
|
100
|
-
},
|
|
101
|
-
"thinkingLevel": "high",
|
|
102
|
-
"promptStack": "reviewer"
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
`autoActivate: true` 会在 Pi 启动全新 session 时一次性应用整个 profile。最多只能有一个 profile 请求自动应用。自动应用的 profile 优先于独立 prompt stack 的自动加载,即使它的 `promptStack` 为 `null` 也不会回退;如果没有 profile 请求自动应用,则继续使用现有的 `default.json`/`autoActivate` stack 规则。已恢复的 session branch 选择优先于这两种自动加载机制。
|
|
107
|
-
|
|
108
|
-
`promptStack` 可以为 `null`。Profile v1 不保存工具名或 skill 列表;引用的 prompt stack 是工具策略和模型可见 skill 过滤的唯一来源。校验会拒绝不支持的字段,避免悄悄保留无效的生成参数或 runner 配置。
|
|
109
|
-
|
|
110
|
-
`/profile preview <id>` 会解析模型、认证、思考等级支持、prompt stack 和最终工具集,但不会改变运行时。`/profile status` 显示上次应用的 profile 和当前 drift;profile provenance 会跟随 session branch 恢复用于状态显示,但 reload、resume、tree navigation 或 compaction 绝不会自动重新应用 profile。全新 session 的自动应用仍然是一次性的,因此之后的手动修改会被保留。
|
|
111
|
-
|
|
112
|
-
### 实验性前台 subagent
|
|
53
|
+
没有其他 stack 或已恢复 session 选择优先时,`default.json` 会自动启用。
|
|
113
54
|
|
|
114
|
-
|
|
55
|
+
### 2. 打开可视化编辑器
|
|
115
56
|
|
|
116
57
|
```text
|
|
117
|
-
/
|
|
118
|
-
/forge-agent plan reviewer 检查这个 API 设计是否正确。
|
|
119
|
-
/forge-agent run reviewer 检查这个 API 设计是否正确。
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
`plan` 会解析 profile 和 stack、编译实际将发送给 provider 的 prompt、校验不可变执行计划,然后丢弃它,不会联系 provider。`/forge-agent run` 和默认配置下的 `forge_subagent` 会先准备完全相同的精确计划,再显示审批界面。默认界面显示 agent 任务、profile/stack、provider、模型、思考等级、最终工具、工作目录、安全边界、payload 大小和执行 fingerprint。选择 **View full prompt** 可以在批准前查看完整 system prompt 和按顺序排列的 provider-bound messages;在查看器中的编辑不会生效。
|
|
123
|
-
|
|
124
|
-
如果要明确允许父 agent 无需逐次审批即可调用 `forge_subagent`,可以在受信任项目的 `.pi/forge/config.json` 中设置:
|
|
125
|
-
|
|
126
|
-
```json
|
|
127
|
-
{
|
|
128
|
-
"subagents": {
|
|
129
|
-
"allowAgentInvocationWithoutApproval": true
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
此选项只影响模型可调用的 `forge_subagent` 工具;`/forge-agent run` 仍然需要交互审批。精确 preflight 和不可变计划校验仍会执行,tool result 也会记录 `trusted-project-config` 授权来源,但 provider transport 会在不向人类显示 prompt 的情况下开始。Profile discovery 会报告当前审批模式。未受信任项目会忽略该设置,格式错误的值会 fail closed。请把项目 config 当作授权文件:除非允许所有能调用 `forge_subagent` 的父 agent 无需再次询问就把编译后的 prompt 和可读文件内容发送给指定 provider,否则不要启用或提交此选项。
|
|
135
|
-
|
|
136
|
-
子 agent 从干净对话开始,不会自动继承主 agent 历史。它在前台运行,并使用 profile 指定的精确模型、思考等级和 prompt stack。候选工具只有 `read`、`grep`、`find` 和 `ls`,还会继续受到 stack 工具策略限制;不会加载 write/edit/shell 工具、skills、prompt templates、context files 或第三方 extensions。最终工具结果包含有界的模型可见报告和可展开的人类可见执行详情。保留的 transcript 会限制每个字符串的大小、删去类似 base64 的文本,并只保留 512 KiB 的滚动尾部,以便保留最终报告而不让 TUI 持有无界工具历史。内联图片数据会留在 child 内供所选视觉模型使用,但专用 report channel 会在任何内容进入主 session 前,把二进制 payload 替换成 MIME type 和编码体积元数据。
|
|
137
|
-
|
|
138
|
-
重要:首个 backend 是 **shared-user**,不是操作系统沙箱。只读是模型工具策略;子进程仍然拥有启动它的用户权限,因此可以读取该用户可读的绝对路径,把内容发送给所选 provider,并把文本保留在父级 tool-result details 中。Host timeout 和取消仅为 best effort。`/tree` 会从当前对话分支移除调用和结果,但被放弃的 entry 仍可能留在 Pi 的磁盘 session JSONL 中;要删除敏感的保留文本,需要删除相应 session 数据。`/tree` 也不能撤销 provider 请求、计费或外部副作用。默认工具集刻意不提供文件系统写入路径;bubblewrap 类沙箱和 staged write mode 留待后续实现。
|
|
139
|
-
|
|
140
|
-
## 使用场景
|
|
141
|
-
|
|
142
|
-
### 🎭 角色扮演 & 创意写作
|
|
143
|
-
|
|
144
|
-
让 Pi 扮演一个角色。在系统提示词中定义性格,用 user message 注入写作风格规则,用 `{{lastUserMessage}}` 在对话历史之后重新插入用户输入。
|
|
145
|
-
|
|
146
|
-
常用模式:
|
|
147
|
-
- 把长期角色规则放在 `system` block。
|
|
148
|
-
- 把 Pi 运行时上下文(工具、技能、项目)放在 `user` slot。
|
|
149
|
-
- 把 `chat-history` slot 设为跳过最新用户消息。
|
|
150
|
-
- 在最后加一个带 `{{lastUserMessage}}` 的 `user` block。
|
|
151
|
-
|
|
152
|
-
这样最新请求会更清晰,也不会重复出现。
|
|
153
|
-
|
|
154
|
-
如果想先从一个基线栈 fork 再改成角色,可以从 [examples/default-prompt-stack.json](examples/default-prompt-stack.json) 开始。
|
|
155
|
-
|
|
156
|
-
### 🧑💻 专注代码审查
|
|
157
|
-
|
|
158
|
-
创建一个 `reviewer.json` 栈,加入严格的审查规则,例如“优先检查正确性、回归风险、安全问题和缺失测试”。保留 `tools`、`project-context`、`variables` 和 `chat-history` slot,这样 Pi 仍然能检查仓库并看到你暴露的模板变量。
|
|
159
|
-
|
|
160
|
-
如果你想保留 Pi 原本的编程行为,只额外加上更严格的审查视角,可以使用 `mode: "append"`。
|
|
161
|
-
|
|
162
|
-
### 🌐 翻译模式
|
|
163
|
-
|
|
164
|
-
创建一个小型 `translator.json` 栈,用一个 system block 指定语气和目标语言,再保留 `chat-history` 和 `{{lastUserMessage}}` 的布局。这样可以在双语润色、直译、产品本地化审查之间快速切换,而不影响默认助手。
|
|
165
|
-
|
|
166
|
-
### 🔀 多模式切换
|
|
167
|
-
|
|
168
|
-
为不同任务创建独立的栈:
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
.pi/forge/prompt-stacks/
|
|
172
|
-
coder.json # 严格编程助手
|
|
173
|
-
writer.json # 创意写作搭档
|
|
174
|
-
translator.json # 双语翻译
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
用 `/preset use coder`、`/preset use writer` 等命令切换。
|
|
178
|
-
|
|
179
|
-
### 🧪 展示 pi-forge 特性的预设
|
|
180
|
-
|
|
181
|
-
- **Pi mirror** — 从 [examples/default-prompt-stack.json](examples/default-prompt-stack.json) 开始。它保留 Pi 的默认行为,同时把每个运行时区块变成可移动、可检查的 slot。
|
|
182
|
-
- **Focused reviewer** — 见 [examples/reviewer-prompt-stack.json](examples/reviewer-prompt-stack.json)。它禁用写文件工具,把旧聊天历史包裹成背景上下文,从 history 中移除最新用户消息,再用 `{{lastUserMessage}}` 作为明确的 review target 插入。
|
|
183
|
-
- **SillyTavern DM writer** — 见 [examples/sillytavern-dm-writer-prompt-stack.json](examples/sillytavern-dm-writer-prompt-stack.json)。它用 `{{char}}` / `{{user}}` 定义 Dungeon Master 角色,包裹旧冒险历史,把 `{{lastUserMessage}}` 作为当前玩家行动重新插入,并用 regex 清理 OOC 注释、暗骰标记、骰子写法和 `Player:` 前缀。
|
|
184
|
-
|
|
185
|
-
### 🔧 模板变量
|
|
186
|
-
|
|
187
|
-
定义稳定的 prompt 常量:
|
|
188
|
-
|
|
189
|
-
```json
|
|
190
|
-
"variables": {
|
|
191
|
-
"char": "Konata",
|
|
192
|
-
"user": "User"
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
在 prompt 文本里用 ST 风格宏做局部变量读写:
|
|
197
|
-
|
|
198
|
-
```
|
|
199
|
-
{{setvar::mood::focused}}
|
|
200
|
-
{{getvar::mood}}
|
|
201
|
-
{{setsessionvar::topic::compiler cleanup}}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
需要长期保存的项目记忆请写入仓库文件,而不是 pi-forge prompt 变量。
|
|
205
|
-
|
|
206
|
-
### 📦 SillyTavern 迁移
|
|
207
|
-
|
|
208
|
-
把 ST 预设导入 Pi:
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
/preset import-silly ~/SillyTavern/presets/my-preset.json
|
|
58
|
+
/preset ui
|
|
212
59
|
```
|
|
213
60
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
可安全表示的 SillyTavern `promptOnly` regex 脚本会作为 history 阶段规则转换成 pi-forge `regex.rules`,包括 full-match token 转换、trim strings、depth 字段和明确的 user/assistant placement。Display-only、prompt/display 混合、DOM/browser、CSS/HTML 美化、JavaScript、不支持的 placement 和无效 regex 脚本会保留为报告项,供手动检查。
|
|
217
|
-
|
|
218
|
-
### 🔍 Prompt 调试
|
|
219
|
-
|
|
220
|
-
查看实际发给模型的内容:
|
|
221
|
-
|
|
222
|
-
```
|
|
223
|
-
/payload next save=.pi/forge/payloads/last.json
|
|
224
|
-
```
|
|
61
|
+
本地编辑器可以新建、fork、校验、预览、导入、导出和删除 prompt stack。切换到 **Agent profiles** 可以管理一次性模型/思考等级/stack 预设,以及实验性 delegation 配置。写入操作要求项目已被信任。
|
|
225
62
|
|
|
226
|
-
|
|
63
|
+
### 3. 保存 profile
|
|
227
64
|
|
|
228
|
-
|
|
65
|
+
先正常配置 Pi,然后捕获当前设置:
|
|
229
66
|
|
|
67
|
+
```text
|
|
68
|
+
/profile save reviewer
|
|
69
|
+
/profile use reviewer
|
|
230
70
|
```
|
|
231
|
-
/preset preview
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## 工作原理
|
|
235
71
|
|
|
236
|
-
|
|
72
|
+
Profile 只应用一次。之后手动修改模型或思考等级会被保留,直到再次应用 profile;当前 prompt stack 的工具策略则会在启用期间持续执行。
|
|
237
73
|
|
|
238
|
-
|
|
239
|
-
|------|------|
|
|
240
|
-
| **Block** | 在指定位置插入的静态文本(系统提示词、用户消息、助手消息) |
|
|
241
|
-
| **Slot** | 来自 Pi 运行时的动态内容 —— 工具、技能、对话历史、日期、项目上下文等 |
|
|
74
|
+
## 基本概念
|
|
242
75
|
|
|
243
|
-
|
|
76
|
+
Prompt stack 是一个有序 JSON 文档,包含:
|
|
244
77
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
5. 应用已启用的 `history` 和 `compiled` 阶段 outgoing regex 规则。
|
|
250
|
-
6. 可选地在 assistant 消息结束时应用破坏性的 `finalize` regex 规则。
|
|
78
|
+
| 类型 | 用途 |
|
|
79
|
+
|---|---|
|
|
80
|
+
| **Block** | 固定的 `system`、`user`、`assistant` 或隐藏 `custom` 文本 |
|
|
81
|
+
| **Slot** | 工具、skills、项目上下文、变量、日期/cwd、聊天历史等运行时内容 |
|
|
251
82
|
|
|
252
|
-
|
|
83
|
+
Stack 可以 `replace`、`append` 或 `prepend` Pi 的基础 system prompt。编译时,pi-forge 会展开宏、插入对话、执行工具策略、过滤自己渲染的 skill 列表,并应用已启用的 regex 规则。
|
|
253
84
|
|
|
254
|
-
|
|
255
|
-
|------|-----------|
|
|
256
|
-
| `chat-history` | 当前对话 |
|
|
257
|
-
| `tools` | 可用工具及其描述 |
|
|
258
|
-
| `tool-guidelines` | 工具使用指导 |
|
|
259
|
-
| `skills` | 已加载的 Pi 技能 |
|
|
260
|
-
| `project-context` | 项目指令和上下文文件 |
|
|
261
|
-
| `variables` | 静态/会话/轮次模板变量 |
|
|
262
|
-
| `date` / `cwd` / `date-cwd` | 当前日期、可选当前时间和工作目录 |
|
|
263
|
-
| `active-model` | 当前使用的模型 |
|
|
264
|
-
| `append-system-prompt` | 用户追加的系统提示词 |
|
|
265
|
-
| `pi-docs` | Pi 文档指导 |
|
|
85
|
+
Agent profile 是项目级预设,引用精确 provider/model、思考等级和 prompt stack。它不会重复保存工具或 skill 策略;被引用的 stack 始终是唯一来源。
|
|
266
86
|
|
|
267
|
-
|
|
87
|
+
推荐从这些示例开始:
|
|
268
88
|
|
|
269
|
-
-
|
|
270
|
-
-
|
|
271
|
-
-
|
|
89
|
+
- [默认 Pi mirror](examples/default-prompt-stack.json):保留 Pi 默认行为,同时让所有区域都可移动。
|
|
90
|
+
- [专注代码审查](examples/reviewer-prompt-stack.json):只读工具策略、背景历史和明确的最新用户目标。
|
|
91
|
+
- [SillyTavern DM writer](examples/sillytavern-dm-writer-prompt-stack.json):角色、变量、历史布局和 regex 清理。
|
|
92
|
+
- [自定义 system-status extension](examples/custom-system-status-extension/README.md):注册可信 macro 和 slot。
|
|
272
93
|
|
|
273
94
|
## 常用命令
|
|
274
95
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
|
278
|
-
|
|
279
|
-
| `/preset
|
|
280
|
-
| `/preset
|
|
281
|
-
| `/preset
|
|
282
|
-
| `/preset
|
|
283
|
-
| `/
|
|
284
|
-
| `/
|
|
285
|
-
| `/
|
|
286
|
-
| `/
|
|
287
|
-
| `/
|
|
288
|
-
| `/preset ui [stop\|restart]` | 打开、停止或重启 Web 编辑器 |
|
|
289
|
-
|
|
290
|
-
### 管理 agent profile
|
|
291
|
-
|
|
292
|
-
| 命令 | 作用 |
|
|
293
|
-
|------|------|
|
|
294
|
-
| `/profile list` | 显示项目 profile 和解析诊断 |
|
|
295
|
-
| `/profile use <id>` | 预检并一次性应用 profile |
|
|
296
|
-
| `/profile save <id> [--overwrite]` | 捕获当前模型、思考等级和 prompt stack |
|
|
297
|
-
| `/profile status` | 显示当前运行时、上次应用来源和 drift |
|
|
298
|
-
| `/profile preview <id>` | 不应用,只预览解析结果和最终工具 |
|
|
299
|
-
| `/profile validate [id]` | 校验一个 profile;省略 id 时校验全部 |
|
|
300
|
-
| `/profile reload` | 从磁盘重新加载 profile,但不应用 |
|
|
301
|
-
| `/profile forget` | 忘记上次应用来源,不改变运行时 |
|
|
302
|
-
|
|
303
|
-
### 实验性前台 subagent
|
|
304
|
-
|
|
305
|
-
| 命令 | 作用 |
|
|
306
|
-
|------|------|
|
|
307
|
-
| `/forge-agent backends` | 显示实验性 backend 及其能力 |
|
|
308
|
-
| `/forge-agent plan <profile> <task>` | 不进行 provider transport,准备、校验、显示并丢弃精确执行计划 |
|
|
309
|
-
| `/forge-agent run <profile> <task>` | 审查精确计划并在批准后运行一个前台只读文本任务 |
|
|
310
|
-
|
|
311
|
-
模型可调用的工具包括用于本地元数据发现的 `forge_subagent_profiles`,以及用于执行的 `forge_subagent`。发现工具不需要审批,也不会请求 provider 或准备 subagent prompt。当前主 agent 工具策略必须允许执行工具;之后还必须存在交互式审批 UI,或者启用上文明确说明的受信任项目免审批选项,subagent 才可运行。
|
|
312
|
-
|
|
313
|
-
### 导入 & 调试
|
|
314
|
-
|
|
315
|
-
| 命令 | 作用 |
|
|
316
|
-
|------|------|
|
|
317
|
-
| `/preset import-silly <path>` | 导入 SillyTavern 预设 |
|
|
318
|
-
| `/intercept` | 显示下一条 provider payload |
|
|
319
|
-
| `/payload next [save=<path>]` | 显示并可保存下一条 payload |
|
|
320
|
-
|
|
321
|
-
## 常用宏
|
|
322
|
-
|
|
323
|
-
在 block 内容中使用这些宏来插入动态值:
|
|
324
|
-
|
|
325
|
-
| 宏 | 展开为 |
|
|
326
|
-
|----|--------|
|
|
327
|
-
| `{{lastUserMessage}}` | 用户最新消息 |
|
|
328
|
-
| `{{date}}` | 当前日期 (YYYY-MM-DD) |
|
|
329
|
-
| `{{time}}` | 当前时间 (HH:MM:SS) |
|
|
330
|
-
| `{{cwd}}` | 当前工作目录 |
|
|
331
|
-
| `{{tools}}` | 逗号分隔的工具名 |
|
|
332
|
-
| `{{selectedTools}}` | 所选工具名的别名 |
|
|
333
|
-
| `{{activeModel}}` | 当前模型 (provider/id) |
|
|
334
|
-
| `{{char}}` / `{{user}}` | 栈中定义的自定义变量 |
|
|
335
|
-
|
|
336
|
-
### 变量宏
|
|
337
|
-
|
|
338
|
-
```
|
|
339
|
-
{{setvar::name::value}} 设置轮次变量(每条消息清空)
|
|
340
|
-
{{setsessionvar::name::value}} 设置会话变量(持久化)
|
|
341
|
-
{{setvar::session::name::value}} 也可设置会话变量
|
|
342
|
-
{{getvar::name}} 读取变量(轮次 → 会话 → 静态)
|
|
343
|
-
{{getturnvar::name}} 只读取轮次变量
|
|
344
|
-
{{getsessionvar::name}} 只读取会话变量
|
|
345
|
-
{{clearvar::name}} 清除变量
|
|
346
|
-
{{clearturnvar::name}} 清除轮次变量
|
|
347
|
-
{{clearsessionvar::name}} 清除会话变量
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
### 过滤和条件宏
|
|
351
|
-
|
|
352
|
-
宏支持嵌套,`::` 分隔符只会在当前宏深度拆分。
|
|
353
|
-
|
|
354
|
-
| 宏 | 展开为 |
|
|
355
|
-
|----|--------|
|
|
356
|
-
| `{{trim::value}}` | 去掉首尾空白后的 `value` |
|
|
357
|
-
| `{{upper::value}}` | 大写 `value` |
|
|
358
|
-
| `{{lower::value}}` | 小写 `value` |
|
|
359
|
-
| `{{json::value}}` | `value` 的 JSON 字符串字面量 |
|
|
360
|
-
| `{{xml::value}}` | XML 转义后的 `value` |
|
|
361
|
-
| `{{ifvar::name::then::else}}` | 变量存在时输出 `then`,否则输出 `else` |
|
|
362
|
-
| `{{ifeq::name::expected::then::else}}` | 变量等于 `expected` 时输出 `then`,否则输出 `else` |
|
|
363
|
-
| `{{iftools::tool::then::else}}` | 当前工具列表包含 `tool` 时输出 `then`,否则输出 `else` |
|
|
364
|
-
| `{{ifslot::slot::then::else}}` | 启用的 stack 条目包含 `slot` 时输出 `then`,否则输出 `else` |
|
|
365
|
-
|
|
366
|
-
条件宏是 lazy 的:只有选中的分支会展开,所以被跳过的分支不会设置或清除变量。最后的 `else` 参数可省略,默认输出空文本。
|
|
367
|
-
|
|
368
|
-
### 可信自定义宏和 slot
|
|
369
|
-
|
|
370
|
-
自定义宏和 slot 由可信扩展代码注册,不把可执行代码写进 prompt-stack JSON。项目本地自定义代码放在 `.pi/forge/extensions/`。机器级个人自定义代码放在 `~/.pi/forge/extensions/`。pi-forge 会在项目受信任后、stack 校验前先加载全局模块,再加载项目本地模块;两个位置都会在 `/preset reload` 时重新加载。
|
|
371
|
-
|
|
372
|
-
这些模块会从 pi-forge 接收注册 API,所以不需要 import `@zihanw/pi-forge`,也不需要知道 pi-forge 安装在哪里。
|
|
373
|
-
|
|
374
|
-
```ts
|
|
375
|
-
// .pi/forge/extensions/ticket-context.ts
|
|
376
|
-
export default function register(api) {
|
|
377
|
-
api.registerMacro({
|
|
378
|
-
name: "ticketId",
|
|
379
|
-
description: "从会话变量读取当前 ticket id。",
|
|
380
|
-
render: (ctx) => ctx.variables.toMacroText(ctx.variables.get("ticket.id")),
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
api.registerSlot({
|
|
384
|
-
name: "ticket-context",
|
|
385
|
-
description: "渲染当前任务的 ticket 上下文。",
|
|
386
|
-
options: {
|
|
387
|
-
heading: { type: "string", default: "Ticket context" },
|
|
388
|
-
},
|
|
389
|
-
render: (ctx) => [
|
|
390
|
-
String(ctx.options.heading ?? "Ticket context") + ":",
|
|
391
|
-
"- Ticket: " + ctx.variables.toMacroText(ctx.variables.get("ticket.id")),
|
|
392
|
-
"- Project: " + ctx.helpers.normalizePath(ctx.runtime.options.cwd),
|
|
393
|
-
].join("\n"),
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
支持 `.ts`、`.js`、`.mjs`、`.cjs` 文件,也支持子目录里的 `index.*`。TypeScript 模块应使用 Node 运行时可直接 strip 的语法;如果需要更复杂的构建,使用 `.js` / `.mjs`。模块可以导出 `default function register(api)`,也可以导出具名 `register(api)`。注册的宏和 slot 名称必须在内置项、全局扩展、项目扩展之间唯一;重复名称会显示为扩展加载 warning。
|
|
399
|
-
|
|
400
|
-
API 包含 `cwd`、`forgeDir`、`extensionPath`、`helpers`、`registerMacro`、`registerSlot`、`getRegisteredMacros`、`getRegisteredSlots`。对全局模块来说,`forgeDir` 是 `~/.pi/forge`;对项目模块来说,它是 `<project>/.pi/forge`。
|
|
401
|
-
|
|
402
|
-
缺失的自定义 slot 会产生校验 warning,直到对应注册模块加载。内置宏和 slot 也使用同一个 registry,可用 `getRegisteredMacros()` 和 `getRegisteredSlots()` 作为实现参考。`/preset diagnostics` 会显示已加载的 pi-forge extension 文件和加载失败信息。
|
|
403
|
-
|
|
404
|
-
完整可复制的扩展和 stack 示例见 [examples/custom-system-status-extension](examples/custom-system-status-extension)。它通过 `.pi/forge/extensions/system-status.ts` 注册 `{{cpuLoad}}` 宏和 `machine-status` slot。
|
|
405
|
-
|
|
406
|
-
可复用的 Pi package 仍然可以从 `@zihanw/pi-forge` import `registerMacro` 和 `registerSlot`。`.pi/forge/extensions` 和 `~/.pi/forge/extensions` loader 主要用于不需要 package 样板的小型可信自定义逻辑。
|
|
407
|
-
|
|
408
|
-
## Stack 参考
|
|
409
|
-
|
|
410
|
-
### 完整条目类型
|
|
411
|
-
|
|
412
|
-
**Block:**
|
|
413
|
-
|
|
414
|
-
```json
|
|
415
|
-
{
|
|
416
|
-
"kind": "block",
|
|
417
|
-
"id": "unique-id",
|
|
418
|
-
"name": "可读标签",
|
|
419
|
-
"enabled": true,
|
|
420
|
-
"role": "system",
|
|
421
|
-
"content": "你的文本。用 {{宏}} 插入动态内容。"
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
有效角色:`system`、`user`、`assistant`、`custom`。
|
|
426
|
-
|
|
427
|
-
**Slot:**
|
|
428
|
-
|
|
429
|
-
```json
|
|
430
|
-
{
|
|
431
|
-
"kind": "slot",
|
|
432
|
-
"id": "unique-id",
|
|
433
|
-
"name": "对话历史",
|
|
434
|
-
"enabled": true,
|
|
435
|
-
"role": "user",
|
|
436
|
-
"slot": "chat-history",
|
|
437
|
-
"options": {
|
|
438
|
-
"includeLastUserMessage": false
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
### Chat history 选项
|
|
444
|
-
|
|
445
|
-
```json
|
|
446
|
-
"options": {
|
|
447
|
-
"includeLastUserMessage": false,
|
|
448
|
-
"stripAssistantThinking": true,
|
|
449
|
-
"includeSummaries": true,
|
|
450
|
-
"toolMode": "keep",
|
|
451
|
-
"roles": ["user", "assistant"],
|
|
452
|
-
"maxMessages": 40,
|
|
453
|
-
"maxChars": 20000
|
|
454
|
-
}
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
当你在 history 之后使用 `{{lastUserMessage}}` 时设为 `false`,避免用户消息出现两次。
|
|
458
|
-
|
|
459
|
-
把 `stripAssistantThinking` 设为 `true` 可以从插入的历史中移除之前 assistant 的 thinking block。可见 assistant 文本、tool call 和 tool result 消息会保留。它只影响这个 slot 插入到模型输入里的 history,不会修改当前 agent loop 或已存储 transcript。
|
|
460
|
-
|
|
461
|
-
使用 `includeSummaries: false` 可以排除 Pi 的 branch/compaction summary 消息;`roles` 可以只保留指定消息角色;`toolMode: "drop"` 可以移除之前的 tool call/tool result history;`maxMessages` / `maxChars` 可以只保留最近 history。当过滤或截断可能拆散 tool-call pair 时,pi-forge 会移除悬空的 tool call/result,避免发送不一致的 tool history。
|
|
462
|
-
|
|
463
|
-
### Date slot 选项
|
|
464
|
-
|
|
465
|
-
在 `date` 或 `date-cwd` slot 上设置 `"includeTime": true`,会在当前日期后加入 `HH:MM:SS` 格式的当前时间。
|
|
466
|
-
|
|
467
|
-
### 结构化 slot 格式选项
|
|
468
|
-
|
|
469
|
-
结构化运行时 slot 默认使用 XML 风格包装。给 `tools`、`tool-guidelines`、`skills`、`project-context` 或 `variables` slot 添加 `"format": "plain"`,可输出更紧凑的换行分隔文本。
|
|
470
|
-
|
|
471
|
-
```json
|
|
472
|
-
{
|
|
473
|
-
"kind": "slot",
|
|
474
|
-
"id": "tools",
|
|
475
|
-
"enabled": true,
|
|
476
|
-
"role": "system",
|
|
477
|
-
"slot": "tools",
|
|
478
|
-
"options": {
|
|
479
|
-
"format": "plain"
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
默认 Pi mirror 示例还会用到几个额外 slot 选项:
|
|
485
|
-
|
|
486
|
-
```json
|
|
487
|
-
{
|
|
488
|
-
"slot": "tools",
|
|
489
|
-
"options": {
|
|
490
|
-
"format": "plain",
|
|
491
|
-
"onlyWithSnippets": true
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
`tools.onlyWithSnippets` 会像 Pi 默认 prompt 一样,只显示带 prompt snippet 的工具。`tool-guidelines.heading`、`tool-guidelines.includePiDefaultGuidelines` 和 `tool-guidelines.piStyle` 用来匹配 Pi 默认的 guidelines 标题和条目。`skills.requireReadTool` 会在 read 工具未启用时隐藏 skills,和 Pi 默认行为一致。
|
|
497
|
-
|
|
498
|
-
### 工具和技能策略
|
|
499
|
-
|
|
500
|
-
Prompt stack 可以用栈级 `allow` 或 `deny` 列表限制 active tools,并过滤模型可见的技能。模式默认精确匹配,也支持 `*` 通配符。
|
|
501
|
-
|
|
502
|
-
```json
|
|
503
|
-
{
|
|
504
|
-
"tools": {
|
|
505
|
-
"allow": ["read", "bash"]
|
|
506
|
-
},
|
|
507
|
-
"skills": {
|
|
508
|
-
"deny": ["browser-danger"]
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
对于工具,`allow` 只保留匹配的 active tools,`deny` 移除匹配的 active tools。对于技能,同样的 pattern 控制哪些技能保留在 pi-forge 渲染的 `skills` slot 中。同一个资源策略不能同时包含非空 `allow` 和 `deny` 列表;混用会产生 validation error。
|
|
514
|
-
|
|
515
|
-
工具策略会在栈激活期间通过 Pi 的 active tool list 强制执行。启动和 reload 时,pi-forge 会等其它扩展完成 `session_start` 工具配置,再记录 baseline 并应用 stack 策略;之后还会在用户输入和 turn 开始前重新应用策略。即使其它扩展稍后调用 `setActiveTools()`,tool-call guard 也会阻止模型执行策略之外的工具。外部扩展新增的工具会保留在可恢复 baseline 中,并在禁用 prompt stack 或切换到没有工具策略的 stack 时恢复。
|
|
516
|
-
|
|
517
|
-
技能策略会过滤 pi-forge `skills` slot 渲染出的技能。它不会禁用显式技能调用,也不是 capability 或安全边界。如果 stack 使用 `mode: "append"` 或 `"prepend"`,Pi base prompt 里可能已经包含未过滤的技能;需要控制模型可见的技能列表时请使用 `mode: "replace"`。
|
|
518
|
-
|
|
519
|
-
### Regex 转换
|
|
520
|
-
|
|
521
|
-
Prompt stack 可以对发给模型的 prompt 文本执行确定性的 regex 替换,也可以选择清理已结束的 assistant 消息。Outgoing 规则支持 `history` 和 `compiled` 阶段。破坏性的最终消息清理使用 `stage: "compiled"`、`effect: "finalize"` 和 `messages` target。真正的 display-only streaming 转换和 provider-payload 重写还不会生效。
|
|
522
|
-
|
|
523
|
-
```json
|
|
524
|
-
"regex": {
|
|
525
|
-
"schemaVersion": 1,
|
|
526
|
-
"rules": [
|
|
527
|
-
{
|
|
528
|
-
"id": "trim-ooc",
|
|
529
|
-
"enabled": true,
|
|
530
|
-
"stage": "history",
|
|
531
|
-
"effect": "outgoing",
|
|
532
|
-
"pattern": "\\(OOC:[^)]+\\)",
|
|
533
|
-
"flags": "gi",
|
|
534
|
-
"replace": "",
|
|
535
|
-
"roles": ["assistant"],
|
|
536
|
-
"maxMessages": 20
|
|
537
|
-
}
|
|
538
|
-
]
|
|
539
|
-
}
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
使用 `stage: "history"` 可以转换 `chat-history` slot 插入的消息。使用 `stage: "compiled"` 并可选配置 `targets: ["system"]`、`["messages"]` 或两者,可以转换最终编译后的 prompt。消息规则可以用 `roles`、`maxMessages`、`maxChars`、`minDepth` 和 `maxDepth` 限制范围,其中 depth `0` 是最新消息。Replacement 使用 JavaScript 语法(`$&` 表示完整匹配,`$1` 表示捕获组;`$0` 也作为完整匹配的别名,`$$` 转义字面 `$`)。`trimStrings` 会从展开后的 replacement match/capture 中移除字面量字符串,对应 SillyTavern 的 Trim Out 行为。支持的 regex flags 是 `g`、`i`、`m`、`s` 和 `u`。
|
|
543
|
-
|
|
544
|
-
要在 streaming 结束后清理一条 assistant 消息,使用 `effect: "finalize"`:
|
|
545
|
-
|
|
546
|
-
```json
|
|
547
|
-
{
|
|
548
|
-
"id": "finalize-ooc",
|
|
549
|
-
"enabled": true,
|
|
550
|
-
"stage": "compiled",
|
|
551
|
-
"effect": "finalize",
|
|
552
|
-
"targets": ["messages"],
|
|
553
|
-
"roles": ["assistant"],
|
|
554
|
-
"pattern": "\\s*\\(OOC:[^)]+\\)",
|
|
555
|
-
"flags": "gi",
|
|
556
|
-
"replace": ""
|
|
557
|
-
}
|
|
558
|
-
```
|
|
96
|
+
| 命令 | 用途 |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `/preset ui [stop\|restart]` | 打开或管理 Web 编辑器 |
|
|
99
|
+
| `/preset list` | 列出 prompt stack |
|
|
100
|
+
| `/preset use <id\|none>` | 选择或禁用 stack |
|
|
101
|
+
| `/preset preview [id]` | 编译 stack,但不发送请求 |
|
|
102
|
+
| `/preset validate [id]` | 校验一个或全部 stack |
|
|
103
|
+
| `/preset diagnostics` | 查看运行时和 extension 诊断 |
|
|
104
|
+
| `/profile list` | 列出并 preflight profile |
|
|
105
|
+
| `/profile save <id> [--overwrite]` | 把当前运行时保存为 profile |
|
|
106
|
+
| `/profile use <id>` | preflight 后一次性应用 profile |
|
|
107
|
+
| `/profile status` | 查看上次应用 provenance 和当前 drift |
|
|
108
|
+
| `/payload next [save=<path>]` | 检查下一个经过脱敏的 provider payload |
|
|
559
109
|
|
|
560
|
-
|
|
110
|
+
完整列表见[命令参考](docs/zh-CN/reference/commands.md)。
|
|
561
111
|
|
|
562
|
-
|
|
112
|
+
## 实验性前台 delegation
|
|
563
113
|
|
|
564
|
-
|
|
114
|
+
pi-forge 可以把明确授权的 profile 作为干净、前台运行的 Pi 子进程。模型通过 `forge_subagent_profiles` 发现可用 profile,再用 `forge_subagent` 调用;用户可以使用 `/forge-agent plan` 和 `/forge-agent run`。
|
|
565
115
|
|
|
566
|
-
|
|
116
|
+
此功能仍是**实验性功能**,profile 默认不能委派。请在受信任项目的 `.pi/forge/config.json` 或 Web 编辑器 delegation 卡片中逐个启用。除非项目明确授权无人值守的模型调用,否则执行前会显示与不可变计划绑定的审批界面。
|
|
567
117
|
|
|
568
|
-
|
|
569
|
-
{
|
|
570
|
-
"kind": "slot",
|
|
571
|
-
"id": "variables",
|
|
572
|
-
"enabled": true,
|
|
573
|
-
"role": "user",
|
|
574
|
-
"slot": "variables",
|
|
575
|
-
"options": {
|
|
576
|
-
"includeStatic": true,
|
|
577
|
-
"includeSession": true,
|
|
578
|
-
"includeTurn": false,
|
|
579
|
-
"format": "xml"
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
```
|
|
118
|
+
> **安全边界:** 当前 backend 是 shared-user 进程,不是操作系统沙箱。“只读”只描述模型可见工具策略。Child 仍有启动用户的 OS 读取权限;可读内容可能发送给所选 provider,并保留在 Pi session 数据中。Timeout 和取消仅为 best effort,`/tree` 不能撤销 provider 请求、计费或外部影响。
|
|
583
119
|
|
|
584
|
-
|
|
120
|
+
启用前必须阅读[前台 delegation 与安全模型](docs/zh-CN/guides/delegation.md)。
|
|
585
121
|
|
|
586
|
-
|
|
587
|
-
git clone https://github.com/MacroSony/pi-forge.git
|
|
588
|
-
cd pi-forge
|
|
589
|
-
npm install
|
|
590
|
-
npm run build
|
|
591
|
-
# .pi/settings.json 会加载 package 构建后的 dist/index.js
|
|
592
|
-
pi # 启动 Pi,信任项目,必要时 /reload
|
|
593
|
-
```
|
|
122
|
+
## 文档导航
|
|
594
123
|
|
|
595
|
-
|
|
124
|
+
### 学习
|
|
596
125
|
|
|
597
|
-
|
|
126
|
+
- [快速上手](docs/zh-CN/getting-started.md)
|
|
127
|
+
- [Prompt stack 概念](docs/zh-CN/concepts/prompt-stacks.md)
|
|
128
|
+
- [Agent profile 概念](docs/zh-CN/concepts/agent-profiles.md)
|
|
129
|
+
- [Web 编辑器](docs/zh-CN/guides/web-editor.md)
|
|
130
|
+
- [前台 delegation](docs/zh-CN/guides/delegation.md)
|
|
598
131
|
|
|
599
|
-
|
|
600
|
-
{
|
|
601
|
-
"packages": ["../pi-forge"]
|
|
602
|
-
}
|
|
603
|
-
```
|
|
132
|
+
### 参考
|
|
604
133
|
|
|
605
|
-
|
|
134
|
+
- [命令](docs/zh-CN/reference/commands.md)
|
|
135
|
+
- [英文 stack schema](docs/reference/stack-schema.md)
|
|
136
|
+
- [英文 macros 与 slots](docs/reference/macros-and-slots.md)
|
|
137
|
+
- [英文配置参考](docs/reference/configuration.md)
|
|
606
138
|
|
|
607
|
-
|
|
608
|
-
{
|
|
609
|
-
"extensions": ["../pi-forge/src/index.ts"]
|
|
610
|
-
}
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
也可以用 `pi -e ../pi-forge/src/index.ts` 做一次性的源码级 smoke test。不要同时加载 package 和 source entry,否则 pi-forge 会初始化两次。修改 browser client 源码后还需要执行 `npm run build:client`,因为本地编辑器提供的是生成后的 browser bundle。
|
|
139
|
+
完整英文文档从 [docs/README.md](docs/README.md) 开始。
|
|
614
140
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
```bash
|
|
618
|
-
npm test
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
运行真实浏览器中的编辑器 smoke test(如果 Chrome 不在标准路径,请设置 `CHROME_PATH`):
|
|
622
|
-
|
|
623
|
-
```bash
|
|
624
|
-
npm run test:browser
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
类型检查:
|
|
628
|
-
|
|
629
|
-
```bash
|
|
630
|
-
npm run typecheck
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
构建 package 输出:
|
|
634
|
-
|
|
635
|
-
```bash
|
|
636
|
-
npm run build
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
运行完整仓库验证,包括在临时目录中执行干净构建,并逐字节检查已跟踪的 `dist/` 是否与 `src/` 一致:
|
|
640
|
-
|
|
641
|
-
```bash
|
|
642
|
-
npm run verify
|
|
643
|
-
```
|
|
141
|
+
## 兼容性原则
|
|
644
142
|
|
|
645
|
-
|
|
143
|
+
- npm 安装不会要求用户跟随某个精确 Pi patch 版本。
|
|
144
|
+
- Release 会分别记录实际测试过的 Pi 最低版本和当前版本。
|
|
145
|
+
- 如果实验性 subagent 依赖的 host capability 不存在,它应在 provider transport 前明确报错并 fail closed。
|
|
146
|
+
- 普通 prompt stack 和 profile 使用不应因为可选 delegation backend 不兼容而失效。
|
|
646
147
|
|
|
647
148
|
## License
|
|
648
149
|
|
|
649
|
-
MIT
|
|
150
|
+
[MIT](LICENSE)
|