@youngjurry/pi-agents 0.7.3 → 0.7.4
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 +6 -0
- package/README.md +1 -1
- package/control.ts +11 -9
- package/package.json +1 -1
- package/roles.ts +8 -9
- package/tools.ts +1 -1
- package/types.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.4 - 2026-09-05
|
|
4
|
+
|
|
5
|
+
- Match Pi's progressive Skill disclosure for sub-agent Roles instead of eagerly injecting complete `SKILL.md` files.
|
|
6
|
+
- Let an omitted `skills` field inherit all discoverable Skills, an explicit list expose only those Skills, and `skills: []` expose none.
|
|
7
|
+
- Preserve explicit unknown-Skill validation and report inherited Role skills as `*` through on-demand Role discovery.
|
|
8
|
+
|
|
3
9
|
## 0.7.3 - 2026-09-05
|
|
4
10
|
|
|
5
11
|
- Fold the full `wait_agent` status tree by default and reuse Pi's `Ctrl+O` expansion state to reveal it on demand.
|
package/README.md
CHANGED
|
@@ -134,7 +134,7 @@ nickname_candidates: [Ada, Grace]
|
|
|
134
134
|
Review carefully and return findings with exact paths.
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
`skills`
|
|
137
|
+
`skills` optionally filters Pi's normal progressive Skill disclosure. Omit the field to inherit all discoverable Skills, specify names such as `skills: [document]` to expose only those Skill names/descriptions/paths, or use `skills: []` to expose none. The child still reads a matching `SKILL.md` on demand rather than placing complete Skill instructions in every prompt. As in Pi's main Agent, the catalog is shown only when `read` or `bash` is active. Unknown explicitly selected Skill names fail clearly instead of being silently ignored.
|
|
138
138
|
|
|
139
139
|
## Model configuration
|
|
140
140
|
|
package/control.ts
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
rootAgentInstructions,
|
|
24
24
|
sanitizeForkMessages,
|
|
25
25
|
} from "./context.ts";
|
|
26
|
-
import { discoverRoles,
|
|
26
|
+
import { discoverRoles, resolveRole, selectRoleSkills } from "./roles.ts";
|
|
27
27
|
import {
|
|
28
28
|
DEFAULT_CHILD_THINKING_LEVEL,
|
|
29
29
|
DEFAULT_MAX_CONCURRENT_SUBAGENTS,
|
|
@@ -594,8 +594,7 @@ export class AgentControl {
|
|
|
594
594
|
assignedSkillNames?: readonly string[],
|
|
595
595
|
): Promise<DefaultResourceLoader> {
|
|
596
596
|
const selfPath = path.resolve(this.selfExtensionPath);
|
|
597
|
-
|
|
598
|
-
loader = new DefaultResourceLoader({
|
|
597
|
+
const loader = new DefaultResourceLoader({
|
|
599
598
|
cwd,
|
|
600
599
|
agentDir: getAgentDir(),
|
|
601
600
|
settingsManager,
|
|
@@ -603,11 +602,14 @@ export class AgentControl {
|
|
|
603
602
|
...base,
|
|
604
603
|
extensions: base.extensions.filter((extension) => path.resolve(extension.resolvedPath) !== selfPath),
|
|
605
604
|
}),
|
|
606
|
-
|
|
607
|
-
base
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
605
|
+
...(assignedSkillNames === undefined ? {} : {
|
|
606
|
+
skillsOverride: (base: ReturnType<DefaultResourceLoader["getSkills"]>) => ({
|
|
607
|
+
...base,
|
|
608
|
+
skills: selectRoleSkills(assignedSkillNames, base.skills),
|
|
609
|
+
}),
|
|
610
|
+
}),
|
|
611
|
+
systemPromptOverride: (base) => [base || "You are a coding agent.", instructions]
|
|
612
|
+
.filter((part) => part.trim()).join("\n\n"),
|
|
611
613
|
});
|
|
612
614
|
await loader.reload();
|
|
613
615
|
this.captureTranscriptToolDefinitions(loader);
|
|
@@ -1151,7 +1153,7 @@ export class AgentControl {
|
|
|
1151
1153
|
model: role.model || settings.defaultModel,
|
|
1152
1154
|
thinkingLevel: role.thinkingLevel ?? settings.defaultThinkingLevel ?? DEFAULT_CHILD_THINKING_LEVEL,
|
|
1153
1155
|
tools: role.tools,
|
|
1154
|
-
skills: role.skills,
|
|
1156
|
+
skills: role.skills ?? ["*"],
|
|
1155
1157
|
source: role.source,
|
|
1156
1158
|
}));
|
|
1157
1159
|
}
|
package/package.json
CHANGED
package/roles.ts
CHANGED
|
@@ -45,6 +45,11 @@ function stringList(value: unknown): string[] | undefined {
|
|
|
45
45
|
return result.length > 0 ? result : undefined;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
function optionalStringList(value: unknown): string[] | undefined {
|
|
49
|
+
if (value === undefined) return undefined;
|
|
50
|
+
return stringList(value) ?? [];
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
function loadDirectory(directory: string, source: "user" | "project"): AgentRole[] {
|
|
49
54
|
if (!fs.existsSync(directory)) return [];
|
|
50
55
|
let entries: fs.Dirent[];
|
|
@@ -68,7 +73,7 @@ function loadDirectory(directory: string, source: "user" | "project"): AgentRole
|
|
|
68
73
|
description: frontmatter.description.trim(),
|
|
69
74
|
systemPrompt: body.trim(),
|
|
70
75
|
tools: stringList(frontmatter.tools),
|
|
71
|
-
skills:
|
|
76
|
+
skills: optionalStringList(frontmatter.skills),
|
|
72
77
|
model: typeof frontmatter.model === "string" ? frontmatter.model.trim() : undefined,
|
|
73
78
|
thinkingLevel: thinking,
|
|
74
79
|
nicknameCandidates: stringList(frontmatter.nickname_candidates),
|
|
@@ -117,18 +122,12 @@ export function resolveRole(cwd: string, projectTrusted: boolean, name?: string)
|
|
|
117
122
|
return role;
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
export function
|
|
121
|
-
if (!requestedNames?.length) return "";
|
|
125
|
+
export function selectRoleSkills(requestedNames: readonly string[], discoveredSkills: readonly Skill[]): Skill[] {
|
|
122
126
|
const skillsByName = new Map(discoveredSkills.map((skill) => [skill.name, skill]));
|
|
123
127
|
const missing = requestedNames.filter((name) => !skillsByName.has(name));
|
|
124
128
|
if (missing.length > 0) {
|
|
125
129
|
const available = [...skillsByName.keys()].sort().join(", ") || "none";
|
|
126
130
|
throw new Error(`Role references unknown skill(s): ${missing.join(", ")}. Available skills: ${available}`);
|
|
127
131
|
}
|
|
128
|
-
|
|
129
|
-
const skill = skillsByName.get(name)!;
|
|
130
|
-
const instructions = fs.readFileSync(skill.filePath, "utf8").trim();
|
|
131
|
-
return `<skill>\nName: ${skill.name}\nLocation: ${skill.filePath}\nBase directory: ${skill.baseDir}\n\n${instructions}\n</skill>`;
|
|
132
|
-
});
|
|
133
|
-
return `<agent_skills>\nThe following Role-selected skills are fully loaded. Follow them when completing the task. Resolve relative paths against each skill's base directory.\n\n${sections.join("\n\n")}\n</agent_skills>`;
|
|
132
|
+
return [...new Set(requestedNames)].map((name) => skillsByName.get(name)!);
|
|
134
133
|
}
|
package/tools.ts
CHANGED
|
@@ -88,7 +88,7 @@ function renderCollaborationResult(
|
|
|
88
88
|
role.model ? `model: ${role.model}` : undefined,
|
|
89
89
|
role.thinkingLevel ? `thinking: ${role.thinkingLevel}` : undefined,
|
|
90
90
|
`tools: ${role.tools?.join(", ") || "default set"}`,
|
|
91
|
-
role.skills
|
|
91
|
+
`skills: ${role.skills.length > 0 ? role.skills.join(", ") : "none"}`,
|
|
92
92
|
].filter(Boolean).join(" · ");
|
|
93
93
|
lines.push(` ${theme.fg("accent", role.name)} — ${role.description}`);
|
|
94
94
|
lines.push(` ${theme.fg("dim", configuration)}`);
|