mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
feat(pi-subagents): 重新启用子 Agent 并使用独立的子 Agent 提示词
- 根包恢复 file:./pi-subagents 依赖与 extensions/subagents.ts 加载 (排在 permission-system 之后、Tool Search 之前),并刷新根锁文件; Agent / get_subagent_result / steer_subagent 权限设为 allow, 子 Agent 内的实际操作仍逐个经权限系统并转发主会话。 - 新增 config/prompt/subagent/:执行者角色 preamble 与组合包自带的 general-purpose / Explore / Plan 定义(替换上游内置,去掉 bash find 冲突规则与写死的 Haiku 模型)。 - pi-subagents 新增 basePrompt / bundledAgentsDir / excludedExtensionPaths 选项:子 Agent 不再嵌入父会话提示词,身份标记置于开头;子会话排除 pi-ask-user。未传选项时保持上游行为。 - system-prompt.ts:customPrompt 自带开场白时不再覆盖(修复子 Agent 角色 与 <active_agent> 身份被抹掉);仅凭 customPrompt 上的 <active_agent> 识别子会话,routing 规则支持 scope,sections 支持 subagentExclude (子会话去掉 memory_policy 与 chrome_profile_bridge)。 - pi-hermes-memory:子会话只读,记忆/skill 写入工具返回错误,后台整理、 纠错检测、会话 flush 与索引写入全部跳过。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
b817d66a11
commit
360d8cffc8
@@ -4,6 +4,7 @@ import { dirname, resolve } from "node:path";
|
||||
|
||||
import {
|
||||
applyToolCatalog,
|
||||
isSubagentCustomPrompt,
|
||||
loadRoutingRules,
|
||||
loadSectionsConfig,
|
||||
loadToolCatalog,
|
||||
@@ -23,8 +24,11 @@ export function getSystemPromptDumpPath(cwd: string): string {
|
||||
return resolve(cwd, DUMP_RELATIVE_PATH);
|
||||
}
|
||||
|
||||
/** The options object as Pi 1.3 normalizes it; the vendored types predate `sections`/`forceSystemPrompt`. */
|
||||
type RuntimePromptOptions = MutablePromptOptions & { forceSystemPrompt?: string };
|
||||
/** The options object as Pi 1.3 normalizes it; `MutablePromptOptions` omits `forceSystemPrompt`/`customPrompt`. */
|
||||
type RuntimePromptOptions = MutablePromptOptions & {
|
||||
forceSystemPrompt?: string;
|
||||
customPrompt?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Injectable seams so the composer can be exercised under `node --test`
|
||||
@@ -105,6 +109,12 @@ export function createSystemPromptComposer(deps: SystemPromptComposerDeps = {}):
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// A subagent session is identified by its customPrompt carrying the
|
||||
// pi-subagents <active_agent/> tag — never by the rendered prompt, which
|
||||
// a main session may legitimately contain the literal tag inside.
|
||||
const isSubagent = isSubagentCustomPrompt(options?.customPrompt);
|
||||
const audience = isSubagent ? "subagent" : "main";
|
||||
|
||||
let routingText = "";
|
||||
if (options) {
|
||||
const missing = applyToolCatalog(options, catalog);
|
||||
@@ -115,14 +125,19 @@ export function createSystemPromptComposer(deps: SystemPromptComposerDeps = {}):
|
||||
ctx.ui.notify(`以下工具未在 config/prompt/tools.jsonc 登记:${missing.join(", ")}`, "warning");
|
||||
}
|
||||
}
|
||||
routingText = renderRouting(routing.rules, options.selectedTools);
|
||||
routingText = renderRouting(routing.rules, options.selectedTools, audience);
|
||||
options.sections ??= {};
|
||||
if (isSubagent) {
|
||||
for (const name of sections.subagentExclude) {
|
||||
delete options.sections[name];
|
||||
}
|
||||
}
|
||||
if (routingText.length > 0) {
|
||||
options.sections.tool_routing = routingText;
|
||||
}
|
||||
options.sections = orderSections(options.sections, sections.order);
|
||||
} else {
|
||||
routingText = renderRouting(routing.rules, undefined);
|
||||
routingText = renderRouting(routing.rules, undefined, audience);
|
||||
}
|
||||
|
||||
let rendered = event.systemPrompt;
|
||||
@@ -132,7 +147,11 @@ export function createSystemPromptComposer(deps: SystemPromptComposerDeps = {}):
|
||||
rendered += `\n\n<tool_routing>\n${routingText}\n</tool_routing>`;
|
||||
}
|
||||
|
||||
const final = preamble ? spliceCover(rendered, preamble) : rendered;
|
||||
// A non-empty customPrompt (pi-subagents agent prompt, SYSTEM.md) owns
|
||||
// the whole preamble — including identities like <active_agent/> that
|
||||
// the permission system reads — so the bundle cover must not replace it.
|
||||
const ownsPreamble = typeof options?.customPrompt === "string" && options.customPrompt.length > 0;
|
||||
const final = preamble && !ownsPreamble ? spliceCover(rendered, preamble) : rendered;
|
||||
lastComposed = final;
|
||||
return { systemPrompt: final };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user