feat: 系统提示词改为单一入口统一管理

多个扩展各自整段改写系统提示词并按加载顺序接力,任一扩展定死提示词后
其余只能做字符串手术,且各上游的工具说明与组合包实际工具格局冲突。

- 新增 extensions/system-prompt.ts 作为唯一出口(加载列表最后),按
  config/prompt/(preamble.md、tools.jsonc、routing.jsonc、sections.jsonc)
  组合开场白、工具简介/规则与 <tool_routing> 分区;替代原封面与
  tool-routing 扩展,/dump-system-prompt 输出最终提示词。
- pi-chrome、pi-ssh、pi-hermes-memory 改为写命名分区,pi-rtk-optimizer
  改写 promptGuidelines,pi-permission-system 直接过滤结构化 skills,
  均不再返回 systemPrompt;pi-chrome 未授权时不再每轮冻结提示词。
- 新增 prompt-guard 代理加载第三方扩展(Hashline、FFF、LSP、
  context-mode):拦截直接改写提示词并按目录覆盖工具说明;context-mode
  去掉与组合包路由冲突的锚点段,保留记忆与恢复快照。
- 消除冲突:bash 简介不再建议 grep/find;Hashline edit 不再称可用 grep
  锚点、不再介绍已关闭的 replace_text;context-mode 读写/网页路由提示。
- 守门测试:工具目录覆盖率、禁用用法检查、context-mode 上游原文锁定;
  AGENTS.md 新增「系统提示词单一所有权」。

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
云服务部-叶林立
2026-10-20 17:53:04 -07:00
co-authored by Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent dc4fe92e27
commit ba164896d2
39 changed files with 1863 additions and 742 deletions
+4
View File
@@ -10,3 +10,7 @@
纯 `ssh2` 连接管理在设计时参考了 <https://github.com/99percentpeople/pi-extensions> 中 `@99percentpeople/pi-ssh-remote` 的 commit `fe4c44f3b4d4b52bd2c31d6d4d5a833c4ad60d9d`。本地实现保留本 fork 专属的 `ssh_*` 工具,不导入该扩展的本地工具覆盖或 OpenSSH 回退模型。
本目录不是 Git submodule,且有意不包含嵌套 `.git`、`node_modules` 或生成的构建产物。未来同步上游时必须从明确 tag 或 commit 审查并移植,不得覆盖本地修改。
## 本地改动
- 已建立连接时的 `before_agent_start` 不再向 `systemPrompt` 文本追加远端指引,而是写入 `event.systemPromptOptions.sections.remote_ssh` 结构化分区;组合包单一提示词出口 `extensions/system-prompt.ts` 统一组装,顺序由 `config/prompt/sections.jsonc` 控制。
+8 -2
View File
@@ -355,8 +355,10 @@ export default function piSshExtension(pi: ExtensionAPI): void {
pi.on("before_agent_start", async (event) => {
if (!connection) return;
// Contribute structurally via a named section: the bundle's single
// system-prompt owner (extensions/system-prompt.ts) composes the final
// prompt; extensions must not return `systemPrompt` themselves.
const guidance =
`\n\n# Remote SSH connection\n\n` +
`An SSH2 connection to configured host ${connection.remote} on port ${connection.port} is active. ` +
`The default read/write/edit/bash/find/grep tools act on the LOCAL machine. ` +
`Use ssh_cd, ssh_read, ssh_write, ssh_edit, ssh_find, ssh_grep, and ssh_bash for explicit remote operations. ` +
@@ -364,6 +366,10 @@ export default function piSshExtension(pi: ExtensionAPI): void {
`Remote operations are rooted at ${connection.remoteCwd}; relative paths resolve against that directory. ` +
`For a persistent workspace change, call ssh_cd as a separate step and wait for its successful result before issuing dependent remote tool calls. ` +
`Each ssh_bash call starts a fresh non-interactive shell, so use command-local cd only for an intentionally temporary change; cd, exports, aliases, and other shell state inside one command do not persist to the next call.`;
return { systemPrompt: `${event.systemPrompt}${guidance}` };
const promptOptions = event.systemPromptOptions as unknown as
| { sections?: Record<string, string> }
| undefined;
if (!promptOptions) return; // hosts without structured options just skip the section
(promptOptions.sections ??= {}).remote_ssh = guidance;
});
}