mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 18:55: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
@@ -61,6 +61,7 @@ import { AGENT_ROOT } from "./paths.js";
|
||||
import { isDatabaseMigrationPending } from "./extension-root-migration.js";
|
||||
import { measureLifecycle, measureLifecycleSync } from "./lifecycle-timing.js";
|
||||
import { createMemoryInitializer, withMemoryInitialization, type EnsureMemoryReady } from "./memory-initialization.js";
|
||||
import { isSubagentSession, markSubagentSession, markSubagentSessionFromPrompt } from "./subagent-mode.js";
|
||||
|
||||
export function resolveProjectSkillDiscovery(
|
||||
skillStore: SkillStore,
|
||||
@@ -195,8 +196,12 @@ export default function (pi: ExtensionAPI) {
|
||||
|
||||
const initialization = createMemoryInitializer(async (ctx) => {
|
||||
const timingPrefix = lazy ? "memory-init" : "session-start";
|
||||
if (lazy) migrateLegacyProjectMemoryDirs(agentRoot, config.projectsMemoryDir);
|
||||
if (!persistenceInitialized) {
|
||||
// Subagent sessions are read-only: skip the write side of initialization
|
||||
// (legacy-dir migration, markdown↔SQLite sync, pruning, backfill) while
|
||||
// still loading the store so memory_search/session_search keep working.
|
||||
const subagent = isSubagentSession(ctx);
|
||||
if (lazy && !subagent) migrateLegacyProjectMemoryDirs(agentRoot, config.projectsMemoryDir);
|
||||
if (!persistenceInitialized && !subagent) {
|
||||
try {
|
||||
await measureLifecycle(`${timingPrefix}.persistence-sync`, async () => {
|
||||
// Startup reconciles the global files plus the current project only:
|
||||
@@ -290,18 +295,25 @@ export default function (pi: ExtensionAPI) {
|
||||
// Skills and pinned instructions must be available even without a lookup.
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
sessionContext = ctx;
|
||||
// session_start runs before before_agent_start; a child's rendered prompt
|
||||
// leads with the <active_agent> tag, so detect it here early enough to
|
||||
// skip the session_start writes below.
|
||||
markSubagentSessionFromPrompt(ctx.getSystemPrompt?.() ?? "", ctx);
|
||||
// Pinned directives must not depend on migration/SQLite being healthy.
|
||||
if (standingStore) await standingStore.load();
|
||||
if (!lazy) await ensureMemoryReady(ctx);
|
||||
refreshSkillProjectContext(ctx.cwd);
|
||||
await skillStore.migrateLegacySkills();
|
||||
await skillStore.ensureDiscoveredRoots();
|
||||
if (!isSubagentSession(ctx)) {
|
||||
await skillStore.migrateLegacySkills();
|
||||
await skillStore.ensureDiscoveredRoots();
|
||||
}
|
||||
});
|
||||
|
||||
registerProjectSkillDiscoveryHandler(pi, skillStore, config.projectsMemoryDir);
|
||||
|
||||
// ── 2. Inject memory policy by default; legacy mode keeps full frozen memory blocks ──
|
||||
pi.on("before_agent_start", async (event, _ctx) => {
|
||||
pi.on("before_agent_start", async (event, ctx) => {
|
||||
markSubagentSession(event, ctx);
|
||||
const promptContext = await buildPromptContext(config, store, projectStoreRef(), projectNameRef(), standingStore);
|
||||
if (!promptContext) return;
|
||||
|
||||
@@ -400,6 +412,7 @@ export default function (pi: ExtensionAPI) {
|
||||
|
||||
// ── 10. Live session indexing ──
|
||||
pi.on("message_end", async (_event, ctx) => {
|
||||
if (isSubagentSession(ctx)) return;
|
||||
// Cold lazy sessions remain in Pi's JSONL files and are backfilled on use.
|
||||
if (lazy && !initialization.isReady()) return;
|
||||
scheduleLiveSessionIndex(dbManager, ctx.sessionManager, {
|
||||
@@ -432,6 +445,7 @@ export default function (pi: ExtensionAPI) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (isSubagentSession(ctx)) return;
|
||||
measureLifecycleSync("shutdown.active-index", () => {
|
||||
const sessionFile = ctx.sessionManager.getSessionFile();
|
||||
if (sessionFile && fs.existsSync(sessionFile)) {
|
||||
|
||||
Reference in New Issue
Block a user