@caupulican/pi-adaptative 0.93.5 → 0.93.7
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 +25 -0
- package/dist/bundled-resources/skills/n-plus-2-architecture/SKILL.md +13 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +5 -20
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts +3 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.js +23 -12
- package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
- package/dist/core/autonomy/gates.d.ts.map +1 -1
- package/dist/core/autonomy/gates.js +24 -26
- package/dist/core/autonomy/gates.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +128 -3
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/session-shutdown.d.ts +9 -0
- package/dist/core/session-shutdown.d.ts.map +1 -0
- package/dist/core/session-shutdown.js +44 -0
- package/dist/core/session-shutdown.js.map +1 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skill-vault.d.ts +6 -2
- package/dist/core/skill-vault.d.ts.map +1 -1
- package/dist/core/skill-vault.js +30 -12
- package/dist/core/skill-vault.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +7 -18
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +2 -3
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +86 -33
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-intent.d.ts +16 -0
- package/dist/core/tools/file-mutation-intent.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-intent.js +51 -2
- package/dist/core/tools/file-mutation-intent.js.map +1 -1
- package/dist/core/tools/persistent-process-coordinator.d.ts +8 -2
- package/dist/core/tools/persistent-process-coordinator.d.ts.map +1 -1
- package/dist/core/tools/persistent-process-coordinator.js +52 -4
- package/dist/core/tools/persistent-process-coordinator.js.map +1 -1
- package/dist/core/tools/shell-execution-session.d.ts +8 -1
- package/dist/core/tools/shell-execution-session.d.ts.map +1 -1
- package/dist/core/tools/shell-execution-session.js +54 -3
- package/dist/core/tools/shell-execution-session.js.map +1 -1
- package/dist/core/tools/shell-session.d.ts +2 -1
- package/dist/core/tools/shell-session.d.ts.map +1 -1
- package/dist/core/tools/shell-session.js +22 -2
- package/dist/core/tools/shell-session.js.map +1 -1
- package/dist/core/tools/skill.d.ts +1 -0
- package/dist/core/tools/skill.d.ts.map +1 -1
- package/dist/core/tools/skill.js +11 -6
- package/dist/core/tools/skill.js.map +1 -1
- package/dist/core/tools/windows-shell-engine.d.ts +1 -1
- package/dist/core/tools/windows-shell-engine.d.ts.map +1 -1
- package/dist/core/tools/windows-shell-engine.js +6 -2
- package/dist/core/tools/windows-shell-engine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +2 -2
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -5
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +4 -7
- package/dist/utils/shell.js.map +1 -1
- package/docs/settings.md +7 -7
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -3,6 +3,7 @@ export declare const DEFAULT_SKILL_IDLE_TIMEOUT_MS: number;
|
|
|
3
3
|
export declare const MAX_ACTIVE_SKILL_BODY_BYTES: number;
|
|
4
4
|
export declare const MIN_ACTIVE_SKILL_BODY_BYTES: number;
|
|
5
5
|
export declare const MAX_LOADED_SKILLS = 3;
|
|
6
|
+
export declare const MAX_PINNED_SKILLS = 2;
|
|
6
7
|
type SkillVaultRequester = "model" | "user";
|
|
7
8
|
type SkillVaultUnloadReason = "explicit" | "idle_expired" | "resource_unavailable" | "budget_exceeded";
|
|
8
9
|
interface LoadedSkill {
|
|
@@ -10,6 +11,7 @@ interface LoadedSkill {
|
|
|
10
11
|
bodyBytes: number;
|
|
11
12
|
systemPromptSection: string;
|
|
12
13
|
requester: SkillVaultRequester;
|
|
14
|
+
pinned: boolean;
|
|
13
15
|
loadedAtMs: number;
|
|
14
16
|
fileDevice: number;
|
|
15
17
|
fileInode: number;
|
|
@@ -27,6 +29,7 @@ type SkillSlotState = ({
|
|
|
27
29
|
export interface SkillSlotStatus {
|
|
28
30
|
state: SkillSlotState["state"];
|
|
29
31
|
name: string;
|
|
32
|
+
pinned: boolean;
|
|
30
33
|
loadedAtMs: number;
|
|
31
34
|
lastUsedAtMs?: number;
|
|
32
35
|
idleForMs?: number;
|
|
@@ -49,10 +52,11 @@ export type SkillLoadResult = {
|
|
|
49
52
|
state: "loaded_pending";
|
|
50
53
|
name: string;
|
|
51
54
|
baseDir: string;
|
|
55
|
+
pinned: boolean;
|
|
52
56
|
evicted?: string[];
|
|
53
57
|
} | {
|
|
54
58
|
ok: false;
|
|
55
|
-
reason: "not_found" | "body_too_large" | "invalid_body" | "read_failed";
|
|
59
|
+
reason: "not_found" | "body_too_large" | "invalid_body" | "read_failed" | "pin_limit";
|
|
56
60
|
message: string;
|
|
57
61
|
};
|
|
58
62
|
export interface SkillVaultControllerOptions {
|
|
@@ -76,7 +80,7 @@ export declare class SkillVaultController {
|
|
|
76
80
|
private contextRevision;
|
|
77
81
|
constructor(options: SkillVaultControllerOptions);
|
|
78
82
|
search(rawQuery: string): SkillSearchResult;
|
|
79
|
-
load(name: string, requester: SkillVaultRequester): SkillLoadResult;
|
|
83
|
+
load(name: string, requester: SkillVaultRequester, pin?: boolean): SkillLoadResult;
|
|
80
84
|
unload(name?: string): {
|
|
81
85
|
ok: true;
|
|
82
86
|
unloaded: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-vault.d.ts","sourceRoot":"","sources":["../../src/core/skill-vault.ts"],"names":[],"mappings":"AAKA,OAAO,EAA+B,KAAK,KAAK,EAAyB,MAAM,aAAa,CAAC;AAG7F,eAAO,MAAM,6BAA6B,QAAiB,CAAC;AAC5D,eAAO,MAAM,2BAA2B,QAAY,CAAC;AACrD,eAAO,MAAM,2BAA2B,QAAW,CAAC;AACpD,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAInC,KAAK,mBAAmB,GAAG,OAAO,GAAG,MAAM,CAAC;AAC5C,KAAK,sBAAsB,GAAG,UAAU,GAAG,cAAc,GAAG,sBAAsB,GAAG,iBAAiB,CAAC;AAEvG,UAAU,WAAW;IACpB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,KAAK,cAAc,GAChB,CAAC;IAAE,KAAK,EAAE,gBAAgB,CAAA;CAAE,GAAG,WAAW,CAAC,GAC3C,CAAC;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAAC,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,MAAM,MAAM,eAAe,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"skill-vault.d.ts","sourceRoot":"","sources":["../../src/core/skill-vault.ts"],"names":[],"mappings":"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"}
|
package/dist/core/skill-vault.js
CHANGED
|
@@ -9,6 +9,7 @@ export const DEFAULT_SKILL_IDLE_TIMEOUT_MS = 10 * 60 * 1000;
|
|
|
9
9
|
export const MAX_ACTIVE_SKILL_BODY_BYTES = 64 * 1024;
|
|
10
10
|
export const MIN_ACTIVE_SKILL_BODY_BYTES = 4 * 1024;
|
|
11
11
|
export const MAX_LOADED_SKILLS = 3;
|
|
12
|
+
export const MAX_PINNED_SKILLS = 2;
|
|
12
13
|
const MAX_SEARCH_RESULTS = 5;
|
|
13
14
|
const MAX_SEARCH_DESCRIPTION_CHARS = 240;
|
|
14
15
|
function compactDescription(description) {
|
|
@@ -46,19 +47,19 @@ function aggregateBodyBytes(slots) {
|
|
|
46
47
|
total += slot.bodyBytes;
|
|
47
48
|
return total;
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
let
|
|
50
|
+
/** Per-skill use is unobservable host-side (every loaded body rides every request), so eviction is honest FIFO by loadedAtMs: oldest unpinned first, oldest pinned only once no unpinned slot remains. */
|
|
51
|
+
function evictionVictimName(slots, excludeName) {
|
|
52
|
+
let victim;
|
|
52
53
|
for (const [name, slot] of slots) {
|
|
53
54
|
if (name === excludeName)
|
|
54
55
|
continue;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if (victim === undefined ||
|
|
57
|
+
(victim.pinned && !slot.pinned) ||
|
|
58
|
+
(victim.pinned === slot.pinned && slot.loadedAtMs < victim.loadedAtMs)) {
|
|
59
|
+
victim = { name, pinned: slot.pinned, loadedAtMs: slot.loadedAtMs };
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
|
-
return
|
|
62
|
+
return victim?.name;
|
|
62
63
|
}
|
|
63
64
|
/** Reserve at most roughly one context token's worth of bytes per advertised context token. */
|
|
64
65
|
export function resolveActiveSkillBodyByteLimit(contextWindow) {
|
|
@@ -95,13 +96,27 @@ export class SkillVaultController {
|
|
|
95
96
|
.map(({ skill }) => ({ name: skill.name, description: compactDescription(skill.description) }));
|
|
96
97
|
return { candidates };
|
|
97
98
|
}
|
|
98
|
-
load(name, requester) {
|
|
99
|
+
load(name, requester, pin = false) {
|
|
99
100
|
const now = this.now();
|
|
100
101
|
this.reconcile(now);
|
|
101
102
|
const skill = this.getSkills().find((candidate) => candidate.name === name && (requester === "user" || !candidate.disableModelInvocation));
|
|
102
103
|
if (!skill) {
|
|
103
104
|
return { ok: false, reason: "not_found", message: `No eligible skill named ${JSON.stringify(name)}.` };
|
|
104
105
|
}
|
|
106
|
+
if (pin) {
|
|
107
|
+
let pinnedCount = 0;
|
|
108
|
+
for (const [slotName, slot] of this.slots) {
|
|
109
|
+
if (slotName !== skill.name && slot.pinned)
|
|
110
|
+
pinnedCount++;
|
|
111
|
+
}
|
|
112
|
+
if (pinnedCount >= MAX_PINNED_SKILLS) {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
reason: "pin_limit",
|
|
116
|
+
message: `At most ${MAX_PINNED_SKILLS} skills can be pinned; unload a pinned skill or reload it without pin first.`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
105
120
|
const maxBodyBytes = this.resolveMaxBodyBytes();
|
|
106
121
|
let before;
|
|
107
122
|
try {
|
|
@@ -155,6 +170,7 @@ export class SkillVaultController {
|
|
|
155
170
|
bodyBytes,
|
|
156
171
|
systemPromptSection: activeSkillContext(skill, body),
|
|
157
172
|
requester,
|
|
173
|
+
pinned: pin,
|
|
158
174
|
loadedAtMs: now,
|
|
159
175
|
fileDevice: file.dev,
|
|
160
176
|
fileInode: file.ino,
|
|
@@ -164,7 +180,7 @@ export class SkillVaultController {
|
|
|
164
180
|
});
|
|
165
181
|
const evicted = [];
|
|
166
182
|
while (next.size > MAX_LOADED_SKILLS || aggregateBodyBytes(next) > maxBodyBytes) {
|
|
167
|
-
const victim =
|
|
183
|
+
const victim = evictionVictimName(next, skill.name);
|
|
168
184
|
if (!victim)
|
|
169
185
|
break;
|
|
170
186
|
next.delete(victim);
|
|
@@ -176,6 +192,7 @@ export class SkillVaultController {
|
|
|
176
192
|
state: "loaded_pending",
|
|
177
193
|
name: skill.name,
|
|
178
194
|
baseDir: skill.baseDir,
|
|
195
|
+
pinned: pin,
|
|
179
196
|
...(evicted.length > 0 ? { evicted } : {}),
|
|
180
197
|
};
|
|
181
198
|
}
|
|
@@ -250,12 +267,13 @@ export class SkillVaultController {
|
|
|
250
267
|
}
|
|
251
268
|
slotStatus(slot, now) {
|
|
252
269
|
if (slot.state === "loaded_pending") {
|
|
253
|
-
return { state: "loaded_pending", name: slot.skill.name, loadedAtMs: slot.loadedAtMs };
|
|
270
|
+
return { state: "loaded_pending", name: slot.skill.name, pinned: slot.pinned, loadedAtMs: slot.loadedAtMs };
|
|
254
271
|
}
|
|
255
272
|
const idleForMs = Math.max(0, now - slot.lastUsedAtMs);
|
|
256
273
|
return {
|
|
257
274
|
state: "active",
|
|
258
275
|
name: slot.skill.name,
|
|
276
|
+
pinned: slot.pinned,
|
|
259
277
|
loadedAtMs: slot.loadedAtMs,
|
|
260
278
|
lastUsedAtMs: slot.lastUsedAtMs,
|
|
261
279
|
idleForMs,
|
|
@@ -278,7 +296,7 @@ export class SkillVaultController {
|
|
|
278
296
|
}
|
|
279
297
|
}
|
|
280
298
|
while (aggregateBodyBytes(next) > maxBodyBytes) {
|
|
281
|
-
const victim =
|
|
299
|
+
const victim = evictionVictimName(next);
|
|
282
300
|
if (!victim)
|
|
283
301
|
break;
|
|
284
302
|
next.delete(victim);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-vault.js","sourceRoot":"","sources":["../../src/core/skill-vault.ts"],"names":[],"mappings":"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","sourcesContent":["import { statSync } from \"node:fs\";\nimport { performance } from \"node:perf_hooks\";\nimport { composeRequestSystemPrompt } from \"@caupulican/pi-agent-core/provider-request-planner\";\nimport { parseFrontmatter } from \"../utils/frontmatter.ts\";\nimport { stripResourceProfileBlocks } from \"./resource-profile-blocks.ts\";\nimport { MAX_SKILL_FRONTMATTER_BYTES, type Skill, type SkillFrontmatter } from \"./skills.ts\";\nimport { readBoundedTextFileSync, sameFileVersion } from \"./util/bounded-file.ts\";\n\nexport const DEFAULT_SKILL_IDLE_TIMEOUT_MS = 10 * 60 * 1000;\nexport const MAX_ACTIVE_SKILL_BODY_BYTES = 64 * 1024;\nexport const MIN_ACTIVE_SKILL_BODY_BYTES = 4 * 1024;\nexport const MAX_LOADED_SKILLS = 3;\nconst MAX_SEARCH_RESULTS = 5;\nconst MAX_SEARCH_DESCRIPTION_CHARS = 240;\n\ntype SkillVaultRequester = \"model\" | \"user\";\ntype SkillVaultUnloadReason = \"explicit\" | \"idle_expired\" | \"resource_unavailable\" | \"budget_exceeded\";\n\ninterface LoadedSkill {\n\tskill: Skill;\n\tbodyBytes: number;\n\tsystemPromptSection: string;\n\trequester: SkillVaultRequester;\n\tloadedAtMs: number;\n\tfileDevice: number;\n\tfileInode: number;\n\tfileSize: number;\n\tfileModifiedAtMs: number;\n\tfileChangedAtMs: number;\n}\n\ntype SkillSlotState =\n\t| ({ state: \"loaded_pending\" } & LoadedSkill)\n\t| ({ state: \"active\"; lastUsedAtMs: number; useCount: number } & LoadedSkill);\n\nexport interface SkillSlotStatus {\n\tstate: SkillSlotState[\"state\"];\n\tname: string;\n\tloadedAtMs: number;\n\tlastUsedAtMs?: number;\n\tidleForMs?: number;\n\texpiresInMs?: number;\n\tuseCount?: number;\n}\n\nexport interface SkillVaultStatus {\n\tidleTimeoutMs: number;\n\tslots: SkillSlotStatus[];\n\treason?: SkillVaultUnloadReason;\n}\n\nexport interface SkillSearchResult {\n\tcandidates: Array<{ name: string; description: string }>;\n}\n\nexport type SkillLoadResult =\n\t| { ok: true; state: \"loaded_pending\"; name: string; baseDir: string; evicted?: string[] }\n\t| { ok: false; reason: \"not_found\" | \"body_too_large\" | \"invalid_body\" | \"read_failed\"; message: string };\n\nexport interface SkillVaultControllerOptions {\n\tgetSkills(): readonly Skill[];\n\tnow?: () => number;\n\tidleTimeoutMs?: number;\n\tgetMaxBodyBytes?: () => number;\n\tonSkillUsed?: (skill: Skill, usedAtMs: number) => void;\n}\n\nfunction compactDescription(description: string): string {\n\tconst normalized = description.replace(/\\s+/g, \" \").trim();\n\tif (normalized.length <= MAX_SEARCH_DESCRIPTION_CHARS) return normalized;\n\treturn `${normalized.slice(0, MAX_SEARCH_DESCRIPTION_CHARS - 1)}…`;\n}\n\nfunction queryTokens(value: string): string[] {\n\treturn [...new Set(value.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? [])];\n}\n\nfunction searchScore(skill: Skill, query: string, tokens: readonly string[]): number {\n\tconst name = skill.name.toLowerCase();\n\tconst description = skill.description.toLowerCase();\n\tlet score = name === query ? 100 : name.includes(query) ? 40 : description.includes(query) ? 20 : 0;\n\tfor (const token of tokens) {\n\t\tif (name === token) score += 16;\n\t\telse if (name.includes(token)) score += 8;\n\t\tif (description.includes(token)) score += 3;\n\t}\n\treturn score;\n}\n\nfunction activeSkillContext(skill: Skill, body: string): string {\n\treturn [`ACTIVE SKILL ${skill.name}`, `BASE ${skill.baseDir}`, \"NON-NEGOTIABLE WHILE ACTIVE:\", body].join(\"\\n\");\n}\n\nfunction slotLastUsedAtMs(slot: SkillSlotState): number {\n\treturn slot.state === \"loaded_pending\" ? slot.loadedAtMs : slot.lastUsedAtMs;\n}\n\nfunction aggregateBodyBytes(slots: ReadonlyMap<string, SkillSlotState>): number {\n\tlet total = 0;\n\tfor (const slot of slots.values()) total += slot.bodyBytes;\n\treturn total;\n}\n\nfunction leastRecentlyUsedName(slots: ReadonlyMap<string, SkillSlotState>, excludeName?: string): string | undefined {\n\tlet lruName: string | undefined;\n\tlet lruUsedAtMs = Number.POSITIVE_INFINITY;\n\tfor (const [name, slot] of slots) {\n\t\tif (name === excludeName) continue;\n\t\tconst usedAtMs = slotLastUsedAtMs(slot);\n\t\tif (usedAtMs < lruUsedAtMs) {\n\t\t\tlruUsedAtMs = usedAtMs;\n\t\t\tlruName = name;\n\t\t}\n\t}\n\treturn lruName;\n}\n\n/** Reserve at most roughly one context token's worth of bytes per advertised context token. */\nexport function resolveActiveSkillBodyByteLimit(contextWindow: number | undefined): number {\n\tif (contextWindow === undefined || !Number.isFinite(contextWindow) || contextWindow <= 0) {\n\t\treturn MAX_ACTIVE_SKILL_BODY_BYTES;\n\t}\n\treturn Math.min(MAX_ACTIVE_SKILL_BODY_BYTES, Math.max(MIN_ACTIVE_SKILL_BODY_BYTES, Math.floor(contextWindow)));\n}\n\n/** One host-owned, event-driven lifecycle for lazy skill discovery and transient context projection. */\nexport class SkillVaultController {\n\tprivate readonly getSkills: () => readonly Skill[];\n\tprivate readonly now: () => number;\n\tprivate readonly idleTimeoutMs: number;\n\tprivate readonly getMaxBodyBytes: () => number;\n\tprivate readonly onSkillUsed: ((skill: Skill, usedAtMs: number) => void) | undefined;\n\tprivate slots = new Map<string, SkillSlotState>();\n\tprivate unloadReason: SkillVaultUnloadReason | undefined;\n\tprivate contextRevision = 0;\n\n\tconstructor(options: SkillVaultControllerOptions) {\n\t\tif (!Number.isFinite(options.idleTimeoutMs ?? DEFAULT_SKILL_IDLE_TIMEOUT_MS)) {\n\t\t\tthrow new TypeError(\"Skill idle timeout must be finite.\");\n\t\t}\n\t\tthis.getSkills = options.getSkills;\n\t\tthis.now = options.now ?? (() => performance.now());\n\t\tthis.idleTimeoutMs = Math.max(1, options.idleTimeoutMs ?? DEFAULT_SKILL_IDLE_TIMEOUT_MS);\n\t\tthis.getMaxBodyBytes = options.getMaxBodyBytes ?? (() => MAX_ACTIVE_SKILL_BODY_BYTES);\n\t\tthis.onSkillUsed = options.onSkillUsed;\n\t}\n\n\tsearch(rawQuery: string): SkillSearchResult {\n\t\tconst query = rawQuery.trim().toLowerCase();\n\t\tconst tokens = queryTokens(query);\n\t\tif (!query || tokens.length === 0) return { candidates: [] };\n\t\tconst candidates = this.getSkills()\n\t\t\t.filter((skill) => !skill.disableModelInvocation)\n\t\t\t.map((skill) => ({ skill, score: searchScore(skill, query, tokens) }))\n\t\t\t.filter((entry) => entry.score > 0)\n\t\t\t.sort((left, right) => right.score - left.score || left.skill.name.localeCompare(right.skill.name))\n\t\t\t.slice(0, MAX_SEARCH_RESULTS)\n\t\t\t.map(({ skill }) => ({ name: skill.name, description: compactDescription(skill.description) }));\n\t\treturn { candidates };\n\t}\n\n\tload(name: string, requester: SkillVaultRequester): SkillLoadResult {\n\t\tconst now = this.now();\n\t\tthis.reconcile(now);\n\t\tconst skill = this.getSkills().find(\n\t\t\t(candidate) => candidate.name === name && (requester === \"user\" || !candidate.disableModelInvocation),\n\t\t);\n\t\tif (!skill) {\n\t\t\treturn { ok: false, reason: \"not_found\", message: `No eligible skill named ${JSON.stringify(name)}.` };\n\t\t}\n\t\tconst maxBodyBytes = this.resolveMaxBodyBytes();\n\t\tlet before: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tbefore = statSync(skill.filePath);\n\t\t} catch (error) {\n\t\t\treturn { ok: false, reason: \"read_failed\", message: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t\tlet raw: string;\n\t\ttry {\n\t\t\traw = readBoundedTextFileSync(\n\t\t\t\tskill.filePath,\n\t\t\t\tmaxBodyBytes + MAX_SKILL_FRONTMATTER_BYTES,\n\t\t\t\t`Skill ${JSON.stringify(skill.name)}`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\treturn message.includes(\"exceeds its byte limit\")\n\t\t\t\t? {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\treason: \"body_too_large\",\n\t\t\t\t\t\tmessage: `Skill body exceeds ${maxBodyBytes} bytes; not truncated.`,\n\t\t\t\t\t}\n\t\t\t\t: { ok: false, reason: \"read_failed\", message };\n\t\t}\n\t\tconst parsed = parseFrontmatter<SkillFrontmatter>(raw);\n\t\tconst currentName = parsed.frontmatter.name ?? skill.name;\n\t\tconst body = stripResourceProfileBlocks(parsed.body).trim();\n\t\tif (currentName !== skill.name || !parsed.frontmatter.description || !body) {\n\t\t\treturn { ok: false, reason: \"invalid_body\", message: \"Skill metadata changed or its body is empty.\" };\n\t\t}\n\t\tconst bodyBytes = Buffer.byteLength(body, \"utf8\");\n\t\tif (bodyBytes > maxBodyBytes) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: \"body_too_large\",\n\t\t\t\tmessage: `Skill body exceeds ${maxBodyBytes} bytes; not truncated.`,\n\t\t\t};\n\t\t}\n\t\tlet file: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tfile = statSync(skill.filePath);\n\t\t} catch (error) {\n\t\t\treturn { ok: false, reason: \"read_failed\", message: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t\tif (!sameFileVersion(before, file)) {\n\t\t\treturn { ok: false, reason: \"read_failed\", message: \"Skill changed while it was being loaded.\" };\n\t\t}\n\t\tconst next = new Map(this.slots);\n\t\tnext.set(skill.name, {\n\t\t\tstate: \"loaded_pending\",\n\t\t\tskill,\n\t\t\tbodyBytes,\n\t\t\tsystemPromptSection: activeSkillContext(skill, body),\n\t\t\trequester,\n\t\t\tloadedAtMs: now,\n\t\t\tfileDevice: file.dev,\n\t\t\tfileInode: file.ino,\n\t\t\tfileSize: file.size,\n\t\t\tfileModifiedAtMs: file.mtimeMs,\n\t\t\tfileChangedAtMs: file.ctimeMs,\n\t\t});\n\t\tconst evicted: string[] = [];\n\t\twhile (next.size > MAX_LOADED_SKILLS || aggregateBodyBytes(next) > maxBodyBytes) {\n\t\t\tconst victim = leastRecentlyUsedName(next, skill.name);\n\t\t\tif (!victim) break;\n\t\t\tnext.delete(victim);\n\t\t\tevicted.push(victim);\n\t\t}\n\t\tthis.replaceState(next);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tstate: \"loaded_pending\",\n\t\t\tname: skill.name,\n\t\t\tbaseDir: skill.baseDir,\n\t\t\t...(evicted.length > 0 ? { evicted } : {}),\n\t\t};\n\t}\n\n\tunload(name?: string): { ok: true; unloaded: string[] } {\n\t\tthis.reconcile(this.now());\n\t\tconst target = name?.trim();\n\t\tconst unloaded = !target ? [...this.slots.keys()] : this.slots.has(target) ? [target] : [];\n\t\tif (unloaded.length > 0) {\n\t\t\tconst next = new Map(this.slots);\n\t\t\tfor (const slotName of unloaded) next.delete(slotName);\n\t\t\tthis.replaceState(next, \"explicit\");\n\t\t}\n\t\treturn { ok: true, unloaded };\n\t}\n\n\tstatus(): SkillVaultStatus {\n\t\tconst now = this.now();\n\t\tthis.reconcile(now);\n\t\tconst slots = [...this.slots.values()].map((slot) => this.slotStatus(slot, now));\n\t\treturn {\n\t\t\tidleTimeoutMs: this.idleTimeoutMs,\n\t\t\tslots,\n\t\t\t...(slots.length === 0 && this.unloadReason ? { reason: this.unloadReason } : {}),\n\t\t};\n\t}\n\n\tcommitSystemPromptSection(): string | undefined {\n\t\tconst now = this.now();\n\t\tthis.reconcile(now);\n\t\tif (this.slots.size === 0) return undefined;\n\t\tconst sections: string[] = [];\n\t\tfor (const [name, slot] of this.slots) {\n\t\t\tsections.push(slot.systemPromptSection);\n\t\t\tconst firstUse = slot.state === \"loaded_pending\";\n\t\t\tconst useCount = firstUse ? 1 : slot.useCount + 1;\n\t\t\tthis.slots.set(name, { ...slot, state: \"active\", lastUsedAtMs: now, useCount });\n\t\t\tif (firstUse) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.onSkillUsed?.(slot.skill, now);\n\t\t\t\t} catch {\n\t\t\t\t\t// Usage telemetry must never block skill application.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn sections.join(\"\\n\\n\");\n\t}\n\n\t/** Model the next request's transient system cost without treating a diagnostic read as use. */\n\tpreviewSystemPromptSection(): string | undefined {\n\t\tthis.reconcile(this.now());\n\t\tif (this.slots.size === 0) return undefined;\n\t\treturn [...this.slots.values()].map((slot) => slot.systemPromptSection).join(\"\\n\\n\");\n\t}\n\n\t/** Compose the exact provider system prompt for read-only diagnostics. */\n\tpreviewRequestSystemPrompt(base: string | undefined): string | undefined {\n\t\treturn composeRequestSystemPrompt(base, this.previewSystemPromptSection());\n\t}\n\n\t/** Monotonic identity for provider-visible skill projection changes. */\n\tgetContextRevision(): number {\n\t\tthis.reconcile(this.now());\n\t\treturn this.contextRevision;\n\t}\n\n\t/** Record host-observed work derived from an active skill, independent of agent cooperation. */\n\tnoteActivity(): void {\n\t\tconst now = this.now();\n\t\tfor (const [name, slot] of this.slots) {\n\t\t\tif (slot.state === \"active\") {\n\t\t\t\tthis.slots.set(name, { ...slot, lastUsedAtMs: now });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate slotStatus(slot: SkillSlotState, now: number): SkillSlotStatus {\n\t\tif (slot.state === \"loaded_pending\") {\n\t\t\treturn { state: \"loaded_pending\", name: slot.skill.name, loadedAtMs: slot.loadedAtMs };\n\t\t}\n\t\tconst idleForMs = Math.max(0, now - slot.lastUsedAtMs);\n\t\treturn {\n\t\t\tstate: \"active\",\n\t\t\tname: slot.skill.name,\n\t\t\tloadedAtMs: slot.loadedAtMs,\n\t\t\tlastUsedAtMs: slot.lastUsedAtMs,\n\t\t\tidleForMs,\n\t\t\texpiresInMs: Math.max(0, this.idleTimeoutMs - idleForMs),\n\t\t\tuseCount: slot.useCount,\n\t\t};\n\t}\n\n\tprivate reconcile(now: number): void {\n\t\tif (this.slots.size === 0) return;\n\t\tconst maxBodyBytes = this.resolveMaxBodyBytes();\n\t\tconst skills = this.getSkills();\n\t\tconst next = new Map(this.slots);\n\t\tlet reason: SkillVaultUnloadReason | undefined;\n\t\tfor (const [name, slot] of this.slots) {\n\t\t\tconst slotReason = this.reconcileSlot(slot, skills, maxBodyBytes, now);\n\t\t\tif (slotReason !== undefined) {\n\t\t\t\tnext.delete(name);\n\t\t\t\treason = slotReason;\n\t\t\t}\n\t\t}\n\t\twhile (aggregateBodyBytes(next) > maxBodyBytes) {\n\t\t\tconst victim = leastRecentlyUsedName(next);\n\t\t\tif (!victim) break;\n\t\t\tnext.delete(victim);\n\t\t\treason = \"budget_exceeded\";\n\t\t}\n\t\tif (next.size !== this.slots.size) {\n\t\t\tthis.replaceState(next, reason);\n\t\t}\n\t}\n\n\tprivate reconcileSlot(\n\t\tslot: SkillSlotState,\n\t\tskills: readonly Skill[],\n\t\tmaxBodyBytes: number,\n\t\tnow: number,\n\t): SkillVaultUnloadReason | undefined {\n\t\tif (slot.bodyBytes > maxBodyBytes) return \"budget_exceeded\";\n\t\tconst currentSkill = skills.find(\n\t\t\t(skill) =>\n\t\t\t\tskill.name === slot.skill.name &&\n\t\t\t\tskill.filePath === slot.skill.filePath &&\n\t\t\t\t(slot.requester === \"user\" || !skill.disableModelInvocation),\n\t\t);\n\t\tif (!currentSkill) return \"resource_unavailable\";\n\t\ttry {\n\t\t\tconst file = statSync(slot.skill.filePath);\n\t\t\tif (\n\t\t\t\tfile.dev !== slot.fileDevice ||\n\t\t\t\tfile.ino !== slot.fileInode ||\n\t\t\t\tfile.size !== slot.fileSize ||\n\t\t\t\tfile.mtimeMs !== slot.fileModifiedAtMs ||\n\t\t\t\tfile.ctimeMs !== slot.fileChangedAtMs\n\t\t\t) {\n\t\t\t\treturn \"resource_unavailable\";\n\t\t\t}\n\t\t} catch {\n\t\t\treturn \"resource_unavailable\";\n\t\t}\n\t\tif (now - slotLastUsedAtMs(slot) >= this.idleTimeoutMs) return \"idle_expired\";\n\t\treturn undefined;\n\t}\n\n\tprivate replaceState(slots: Map<string, SkillSlotState>, unloadReason?: SkillVaultUnloadReason): void {\n\t\tthis.slots = slots;\n\t\tif (unloadReason !== undefined) this.unloadReason = unloadReason;\n\t\tthis.contextRevision++;\n\t}\n\n\tprivate resolveMaxBodyBytes(): number {\n\t\tconst configured = this.getMaxBodyBytes();\n\t\tif (!Number.isFinite(configured)) return 1;\n\t\treturn Math.min(MAX_ACTIVE_SKILL_BODY_BYTES, Math.max(1, Math.floor(configured)));\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"skill-vault.js","sourceRoot":"","sources":["../../src/core/skill-vault.ts"],"names":[],"mappings":"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","sourcesContent":["import { statSync } from \"node:fs\";\nimport { performance } from \"node:perf_hooks\";\nimport { composeRequestSystemPrompt } from \"@caupulican/pi-agent-core/provider-request-planner\";\nimport { parseFrontmatter } from \"../utils/frontmatter.ts\";\nimport { stripResourceProfileBlocks } from \"./resource-profile-blocks.ts\";\nimport { MAX_SKILL_FRONTMATTER_BYTES, type Skill, type SkillFrontmatter } from \"./skills.ts\";\nimport { readBoundedTextFileSync, sameFileVersion } from \"./util/bounded-file.ts\";\n\nexport const DEFAULT_SKILL_IDLE_TIMEOUT_MS = 10 * 60 * 1000;\nexport const MAX_ACTIVE_SKILL_BODY_BYTES = 64 * 1024;\nexport const MIN_ACTIVE_SKILL_BODY_BYTES = 4 * 1024;\nexport const MAX_LOADED_SKILLS = 3;\nexport const MAX_PINNED_SKILLS = 2;\nconst MAX_SEARCH_RESULTS = 5;\nconst MAX_SEARCH_DESCRIPTION_CHARS = 240;\n\ntype SkillVaultRequester = \"model\" | \"user\";\ntype SkillVaultUnloadReason = \"explicit\" | \"idle_expired\" | \"resource_unavailable\" | \"budget_exceeded\";\n\ninterface LoadedSkill {\n\tskill: Skill;\n\tbodyBytes: number;\n\tsystemPromptSection: string;\n\trequester: SkillVaultRequester;\n\tpinned: boolean;\n\tloadedAtMs: number;\n\tfileDevice: number;\n\tfileInode: number;\n\tfileSize: number;\n\tfileModifiedAtMs: number;\n\tfileChangedAtMs: number;\n}\n\ntype SkillSlotState =\n\t| ({ state: \"loaded_pending\" } & LoadedSkill)\n\t| ({ state: \"active\"; lastUsedAtMs: number; useCount: number } & LoadedSkill);\n\nexport interface SkillSlotStatus {\n\tstate: SkillSlotState[\"state\"];\n\tname: string;\n\tpinned: boolean;\n\tloadedAtMs: number;\n\tlastUsedAtMs?: number;\n\tidleForMs?: number;\n\texpiresInMs?: number;\n\tuseCount?: number;\n}\n\nexport interface SkillVaultStatus {\n\tidleTimeoutMs: number;\n\tslots: SkillSlotStatus[];\n\treason?: SkillVaultUnloadReason;\n}\n\nexport interface SkillSearchResult {\n\tcandidates: Array<{ name: string; description: string }>;\n}\n\nexport type SkillLoadResult =\n\t| { ok: true; state: \"loaded_pending\"; name: string; baseDir: string; pinned: boolean; evicted?: string[] }\n\t| {\n\t\t\tok: false;\n\t\t\treason: \"not_found\" | \"body_too_large\" | \"invalid_body\" | \"read_failed\" | \"pin_limit\";\n\t\t\tmessage: string;\n\t };\n\nexport interface SkillVaultControllerOptions {\n\tgetSkills(): readonly Skill[];\n\tnow?: () => number;\n\tidleTimeoutMs?: number;\n\tgetMaxBodyBytes?: () => number;\n\tonSkillUsed?: (skill: Skill, usedAtMs: number) => void;\n}\n\nfunction compactDescription(description: string): string {\n\tconst normalized = description.replace(/\\s+/g, \" \").trim();\n\tif (normalized.length <= MAX_SEARCH_DESCRIPTION_CHARS) return normalized;\n\treturn `${normalized.slice(0, MAX_SEARCH_DESCRIPTION_CHARS - 1)}…`;\n}\n\nfunction queryTokens(value: string): string[] {\n\treturn [...new Set(value.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? [])];\n}\n\nfunction searchScore(skill: Skill, query: string, tokens: readonly string[]): number {\n\tconst name = skill.name.toLowerCase();\n\tconst description = skill.description.toLowerCase();\n\tlet score = name === query ? 100 : name.includes(query) ? 40 : description.includes(query) ? 20 : 0;\n\tfor (const token of tokens) {\n\t\tif (name === token) score += 16;\n\t\telse if (name.includes(token)) score += 8;\n\t\tif (description.includes(token)) score += 3;\n\t}\n\treturn score;\n}\n\nfunction activeSkillContext(skill: Skill, body: string): string {\n\treturn [`ACTIVE SKILL ${skill.name}`, `BASE ${skill.baseDir}`, \"NON-NEGOTIABLE WHILE ACTIVE:\", body].join(\"\\n\");\n}\n\nfunction slotLastUsedAtMs(slot: SkillSlotState): number {\n\treturn slot.state === \"loaded_pending\" ? slot.loadedAtMs : slot.lastUsedAtMs;\n}\n\nfunction aggregateBodyBytes(slots: ReadonlyMap<string, SkillSlotState>): number {\n\tlet total = 0;\n\tfor (const slot of slots.values()) total += slot.bodyBytes;\n\treturn total;\n}\n\n/** Per-skill use is unobservable host-side (every loaded body rides every request), so eviction is honest FIFO by loadedAtMs: oldest unpinned first, oldest pinned only once no unpinned slot remains. */\nfunction evictionVictimName(slots: ReadonlyMap<string, SkillSlotState>, excludeName?: string): string | undefined {\n\tlet victim: { name: string; pinned: boolean; loadedAtMs: number } | undefined;\n\tfor (const [name, slot] of slots) {\n\t\tif (name === excludeName) continue;\n\t\tif (\n\t\t\tvictim === undefined ||\n\t\t\t(victim.pinned && !slot.pinned) ||\n\t\t\t(victim.pinned === slot.pinned && slot.loadedAtMs < victim.loadedAtMs)\n\t\t) {\n\t\t\tvictim = { name, pinned: slot.pinned, loadedAtMs: slot.loadedAtMs };\n\t\t}\n\t}\n\treturn victim?.name;\n}\n\n/** Reserve at most roughly one context token's worth of bytes per advertised context token. */\nexport function resolveActiveSkillBodyByteLimit(contextWindow: number | undefined): number {\n\tif (contextWindow === undefined || !Number.isFinite(contextWindow) || contextWindow <= 0) {\n\t\treturn MAX_ACTIVE_SKILL_BODY_BYTES;\n\t}\n\treturn Math.min(MAX_ACTIVE_SKILL_BODY_BYTES, Math.max(MIN_ACTIVE_SKILL_BODY_BYTES, Math.floor(contextWindow)));\n}\n\n/** One host-owned, event-driven lifecycle for lazy skill discovery and transient context projection. */\nexport class SkillVaultController {\n\tprivate readonly getSkills: () => readonly Skill[];\n\tprivate readonly now: () => number;\n\tprivate readonly idleTimeoutMs: number;\n\tprivate readonly getMaxBodyBytes: () => number;\n\tprivate readonly onSkillUsed: ((skill: Skill, usedAtMs: number) => void) | undefined;\n\tprivate slots = new Map<string, SkillSlotState>();\n\tprivate unloadReason: SkillVaultUnloadReason | undefined;\n\tprivate contextRevision = 0;\n\n\tconstructor(options: SkillVaultControllerOptions) {\n\t\tif (!Number.isFinite(options.idleTimeoutMs ?? DEFAULT_SKILL_IDLE_TIMEOUT_MS)) {\n\t\t\tthrow new TypeError(\"Skill idle timeout must be finite.\");\n\t\t}\n\t\tthis.getSkills = options.getSkills;\n\t\tthis.now = options.now ?? (() => performance.now());\n\t\tthis.idleTimeoutMs = Math.max(1, options.idleTimeoutMs ?? DEFAULT_SKILL_IDLE_TIMEOUT_MS);\n\t\tthis.getMaxBodyBytes = options.getMaxBodyBytes ?? (() => MAX_ACTIVE_SKILL_BODY_BYTES);\n\t\tthis.onSkillUsed = options.onSkillUsed;\n\t}\n\n\tsearch(rawQuery: string): SkillSearchResult {\n\t\tconst query = rawQuery.trim().toLowerCase();\n\t\tconst tokens = queryTokens(query);\n\t\tif (!query || tokens.length === 0) return { candidates: [] };\n\t\tconst candidates = this.getSkills()\n\t\t\t.filter((skill) => !skill.disableModelInvocation)\n\t\t\t.map((skill) => ({ skill, score: searchScore(skill, query, tokens) }))\n\t\t\t.filter((entry) => entry.score > 0)\n\t\t\t.sort((left, right) => right.score - left.score || left.skill.name.localeCompare(right.skill.name))\n\t\t\t.slice(0, MAX_SEARCH_RESULTS)\n\t\t\t.map(({ skill }) => ({ name: skill.name, description: compactDescription(skill.description) }));\n\t\treturn { candidates };\n\t}\n\n\tload(name: string, requester: SkillVaultRequester, pin = false): SkillLoadResult {\n\t\tconst now = this.now();\n\t\tthis.reconcile(now);\n\t\tconst skill = this.getSkills().find(\n\t\t\t(candidate) => candidate.name === name && (requester === \"user\" || !candidate.disableModelInvocation),\n\t\t);\n\t\tif (!skill) {\n\t\t\treturn { ok: false, reason: \"not_found\", message: `No eligible skill named ${JSON.stringify(name)}.` };\n\t\t}\n\t\tif (pin) {\n\t\t\tlet pinnedCount = 0;\n\t\t\tfor (const [slotName, slot] of this.slots) {\n\t\t\t\tif (slotName !== skill.name && slot.pinned) pinnedCount++;\n\t\t\t}\n\t\t\tif (pinnedCount >= MAX_PINNED_SKILLS) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\treason: \"pin_limit\",\n\t\t\t\t\tmessage: `At most ${MAX_PINNED_SKILLS} skills can be pinned; unload a pinned skill or reload it without pin first.`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tconst maxBodyBytes = this.resolveMaxBodyBytes();\n\t\tlet before: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tbefore = statSync(skill.filePath);\n\t\t} catch (error) {\n\t\t\treturn { ok: false, reason: \"read_failed\", message: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t\tlet raw: string;\n\t\ttry {\n\t\t\traw = readBoundedTextFileSync(\n\t\t\t\tskill.filePath,\n\t\t\t\tmaxBodyBytes + MAX_SKILL_FRONTMATTER_BYTES,\n\t\t\t\t`Skill ${JSON.stringify(skill.name)}`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\treturn message.includes(\"exceeds its byte limit\")\n\t\t\t\t? {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\treason: \"body_too_large\",\n\t\t\t\t\t\tmessage: `Skill body exceeds ${maxBodyBytes} bytes; not truncated.`,\n\t\t\t\t\t}\n\t\t\t\t: { ok: false, reason: \"read_failed\", message };\n\t\t}\n\t\tconst parsed = parseFrontmatter<SkillFrontmatter>(raw);\n\t\tconst currentName = parsed.frontmatter.name ?? skill.name;\n\t\tconst body = stripResourceProfileBlocks(parsed.body).trim();\n\t\tif (currentName !== skill.name || !parsed.frontmatter.description || !body) {\n\t\t\treturn { ok: false, reason: \"invalid_body\", message: \"Skill metadata changed or its body is empty.\" };\n\t\t}\n\t\tconst bodyBytes = Buffer.byteLength(body, \"utf8\");\n\t\tif (bodyBytes > maxBodyBytes) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: \"body_too_large\",\n\t\t\t\tmessage: `Skill body exceeds ${maxBodyBytes} bytes; not truncated.`,\n\t\t\t};\n\t\t}\n\t\tlet file: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tfile = statSync(skill.filePath);\n\t\t} catch (error) {\n\t\t\treturn { ok: false, reason: \"read_failed\", message: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t\tif (!sameFileVersion(before, file)) {\n\t\t\treturn { ok: false, reason: \"read_failed\", message: \"Skill changed while it was being loaded.\" };\n\t\t}\n\t\tconst next = new Map(this.slots);\n\t\tnext.set(skill.name, {\n\t\t\tstate: \"loaded_pending\",\n\t\t\tskill,\n\t\t\tbodyBytes,\n\t\t\tsystemPromptSection: activeSkillContext(skill, body),\n\t\t\trequester,\n\t\t\tpinned: pin,\n\t\t\tloadedAtMs: now,\n\t\t\tfileDevice: file.dev,\n\t\t\tfileInode: file.ino,\n\t\t\tfileSize: file.size,\n\t\t\tfileModifiedAtMs: file.mtimeMs,\n\t\t\tfileChangedAtMs: file.ctimeMs,\n\t\t});\n\t\tconst evicted: string[] = [];\n\t\twhile (next.size > MAX_LOADED_SKILLS || aggregateBodyBytes(next) > maxBodyBytes) {\n\t\t\tconst victim = evictionVictimName(next, skill.name);\n\t\t\tif (!victim) break;\n\t\t\tnext.delete(victim);\n\t\t\tevicted.push(victim);\n\t\t}\n\t\tthis.replaceState(next);\n\t\treturn {\n\t\t\tok: true,\n\t\t\tstate: \"loaded_pending\",\n\t\t\tname: skill.name,\n\t\t\tbaseDir: skill.baseDir,\n\t\t\tpinned: pin,\n\t\t\t...(evicted.length > 0 ? { evicted } : {}),\n\t\t};\n\t}\n\n\tunload(name?: string): { ok: true; unloaded: string[] } {\n\t\tthis.reconcile(this.now());\n\t\tconst target = name?.trim();\n\t\tconst unloaded = !target ? [...this.slots.keys()] : this.slots.has(target) ? [target] : [];\n\t\tif (unloaded.length > 0) {\n\t\t\tconst next = new Map(this.slots);\n\t\t\tfor (const slotName of unloaded) next.delete(slotName);\n\t\t\tthis.replaceState(next, \"explicit\");\n\t\t}\n\t\treturn { ok: true, unloaded };\n\t}\n\n\tstatus(): SkillVaultStatus {\n\t\tconst now = this.now();\n\t\tthis.reconcile(now);\n\t\tconst slots = [...this.slots.values()].map((slot) => this.slotStatus(slot, now));\n\t\treturn {\n\t\t\tidleTimeoutMs: this.idleTimeoutMs,\n\t\t\tslots,\n\t\t\t...(slots.length === 0 && this.unloadReason ? { reason: this.unloadReason } : {}),\n\t\t};\n\t}\n\n\tcommitSystemPromptSection(): string | undefined {\n\t\tconst now = this.now();\n\t\tthis.reconcile(now);\n\t\tif (this.slots.size === 0) return undefined;\n\t\tconst sections: string[] = [];\n\t\tfor (const [name, slot] of this.slots) {\n\t\t\tsections.push(slot.systemPromptSection);\n\t\t\tconst firstUse = slot.state === \"loaded_pending\";\n\t\t\tconst useCount = firstUse ? 1 : slot.useCount + 1;\n\t\t\tthis.slots.set(name, { ...slot, state: \"active\", lastUsedAtMs: now, useCount });\n\t\t\tif (firstUse) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.onSkillUsed?.(slot.skill, now);\n\t\t\t\t} catch {\n\t\t\t\t\t// Usage telemetry must never block skill application.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn sections.join(\"\\n\\n\");\n\t}\n\n\t/** Model the next request's transient system cost without treating a diagnostic read as use. */\n\tpreviewSystemPromptSection(): string | undefined {\n\t\tthis.reconcile(this.now());\n\t\tif (this.slots.size === 0) return undefined;\n\t\treturn [...this.slots.values()].map((slot) => slot.systemPromptSection).join(\"\\n\\n\");\n\t}\n\n\t/** Compose the exact provider system prompt for read-only diagnostics. */\n\tpreviewRequestSystemPrompt(base: string | undefined): string | undefined {\n\t\treturn composeRequestSystemPrompt(base, this.previewSystemPromptSection());\n\t}\n\n\t/** Monotonic identity for provider-visible skill projection changes. */\n\tgetContextRevision(): number {\n\t\tthis.reconcile(this.now());\n\t\treturn this.contextRevision;\n\t}\n\n\t/** Record host-observed work derived from an active skill, independent of agent cooperation. */\n\tnoteActivity(): void {\n\t\tconst now = this.now();\n\t\tfor (const [name, slot] of this.slots) {\n\t\t\tif (slot.state === \"active\") {\n\t\t\t\tthis.slots.set(name, { ...slot, lastUsedAtMs: now });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate slotStatus(slot: SkillSlotState, now: number): SkillSlotStatus {\n\t\tif (slot.state === \"loaded_pending\") {\n\t\t\treturn { state: \"loaded_pending\", name: slot.skill.name, pinned: slot.pinned, loadedAtMs: slot.loadedAtMs };\n\t\t}\n\t\tconst idleForMs = Math.max(0, now - slot.lastUsedAtMs);\n\t\treturn {\n\t\t\tstate: \"active\",\n\t\t\tname: slot.skill.name,\n\t\t\tpinned: slot.pinned,\n\t\t\tloadedAtMs: slot.loadedAtMs,\n\t\t\tlastUsedAtMs: slot.lastUsedAtMs,\n\t\t\tidleForMs,\n\t\t\texpiresInMs: Math.max(0, this.idleTimeoutMs - idleForMs),\n\t\t\tuseCount: slot.useCount,\n\t\t};\n\t}\n\n\tprivate reconcile(now: number): void {\n\t\tif (this.slots.size === 0) return;\n\t\tconst maxBodyBytes = this.resolveMaxBodyBytes();\n\t\tconst skills = this.getSkills();\n\t\tconst next = new Map(this.slots);\n\t\tlet reason: SkillVaultUnloadReason | undefined;\n\t\tfor (const [name, slot] of this.slots) {\n\t\t\tconst slotReason = this.reconcileSlot(slot, skills, maxBodyBytes, now);\n\t\t\tif (slotReason !== undefined) {\n\t\t\t\tnext.delete(name);\n\t\t\t\treason = slotReason;\n\t\t\t}\n\t\t}\n\t\twhile (aggregateBodyBytes(next) > maxBodyBytes) {\n\t\t\tconst victim = evictionVictimName(next);\n\t\t\tif (!victim) break;\n\t\t\tnext.delete(victim);\n\t\t\treason = \"budget_exceeded\";\n\t\t}\n\t\tif (next.size !== this.slots.size) {\n\t\t\tthis.replaceState(next, reason);\n\t\t}\n\t}\n\n\tprivate reconcileSlot(\n\t\tslot: SkillSlotState,\n\t\tskills: readonly Skill[],\n\t\tmaxBodyBytes: number,\n\t\tnow: number,\n\t): SkillVaultUnloadReason | undefined {\n\t\tif (slot.bodyBytes > maxBodyBytes) return \"budget_exceeded\";\n\t\tconst currentSkill = skills.find(\n\t\t\t(skill) =>\n\t\t\t\tskill.name === slot.skill.name &&\n\t\t\t\tskill.filePath === slot.skill.filePath &&\n\t\t\t\t(slot.requester === \"user\" || !skill.disableModelInvocation),\n\t\t);\n\t\tif (!currentSkill) return \"resource_unavailable\";\n\t\ttry {\n\t\t\tconst file = statSync(slot.skill.filePath);\n\t\t\tif (\n\t\t\t\tfile.dev !== slot.fileDevice ||\n\t\t\t\tfile.ino !== slot.fileInode ||\n\t\t\t\tfile.size !== slot.fileSize ||\n\t\t\t\tfile.mtimeMs !== slot.fileModifiedAtMs ||\n\t\t\t\tfile.ctimeMs !== slot.fileChangedAtMs\n\t\t\t) {\n\t\t\t\treturn \"resource_unavailable\";\n\t\t\t}\n\t\t} catch {\n\t\t\treturn \"resource_unavailable\";\n\t\t}\n\t\tif (now - slotLastUsedAtMs(slot) >= this.idleTimeoutMs) return \"idle_expired\";\n\t\treturn undefined;\n\t}\n\n\tprivate replaceState(slots: Map<string, SkillSlotState>, unloadReason?: SkillVaultUnloadReason): void {\n\t\tthis.slots = slots;\n\t\tif (unloadReason !== undefined) this.unloadReason = unloadReason;\n\t\tthis.contextRevision++;\n\t}\n\n\tprivate resolveMaxBodyBytes(): number {\n\t\tconst configured = this.getMaxBodyBytes();\n\t\tif (!Number.isFinite(configured)) return 1;\n\t\treturn Math.min(MAX_ACTIVE_SKILL_BODY_BYTES, Math.max(1, Math.floor(configured)));\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAA4C,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE9G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,wBAAwB;IACxC,mGAAmG;IACnG,eAAe,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,eAAe,GAAG,YAAY,GAAG,sBAAsB,CAAC,CAAC;IAClH,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,wFAAwF;IACxF,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,iGAAiG;IACjG,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAA4C,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE9G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,wBAAwB;IACxC,mGAAmG;IACnG,eAAe,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,eAAe,GAAG,YAAY,GAAG,sBAAsB,CAAC,CAAC;IAClH,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,wFAAwF;IACxF,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,iGAAiG;IACjG,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB;AAkKD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAqJ3E"}
|
|
@@ -13,7 +13,8 @@ ULTRA-TERSE OUTPUT
|
|
|
13
13
|
|
|
14
14
|
- Drop articles/filler/pleasantries/hedging; fragments valid. Strip conjunctions only when clear; each fact once.
|
|
15
15
|
- Never drop not/never/no/only/except; never invent abbreviations or use causal arrows. Preserve numbers, units, code symbols, function/API names, commands, errors.
|
|
16
|
-
- No self-reference/tool narration/tables/emoji/log dumps. Keep user language. Full grammar: security, irreversible actions, ambiguous order. Replies terse; artifacts normal prose
|
|
16
|
+
- No self-reference/tool narration/tables/emoji/log dumps. Keep user language. Full grammar: security, irreversible actions, ambiguous order. Replies terse; artifacts normal prose.
|
|
17
|
+
- Answer shape: status/ops turns terse; analysis/review/evaluation asks get complete structured answers; never restate harness protocol text or failure-record JSON to the user as an answer.`;
|
|
17
18
|
const PI_ADAPTATIVE_CORE_SECTION = `
|
|
18
19
|
|
|
19
20
|
OPERATING CONTRACT
|
|
@@ -23,31 +24,19 @@ OPERATING CONTRACT
|
|
|
23
24
|
- User outcome governs, method does not. Outcome risk: show evidence, test when practical, offer safest effective path, execute.
|
|
24
25
|
- Work over 15 seconds: managed background run, event terminal, bounded handoff, owner notice; never poll.
|
|
25
26
|
- Delegate independent work within host bounds; root integrates/verifies. Facts: memory, specialization: skills, behavior: source; discard noise.
|
|
27
|
+
- Implementation/verification work loads skill evidence-gated-tdd; architecture/performance design loads skill n-plus-2-architecture; their gates bind only while that work is active.
|
|
28
|
+
- Explicit user instruction in current message overrides standing style (length/format/tone); security, untrusted-content, and authorization rules are never overridable.
|
|
26
29
|
- Ask before broader scope, credential or authentication change/disclosure, destructive action, publication. Bound, source-label output; show paths.
|
|
27
|
-
- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}
|
|
28
|
-
|
|
29
|
-
N+2 ARCHITECTURE
|
|
30
|
-
|
|
31
|
-
Language-agnostic principles:
|
|
32
|
-
1. Bounded flat arenas/pools/rings/chunks, batch recycle.
|
|
33
|
-
2. Safe zero/default data/state, no hidden allocation, one activation owner.
|
|
34
|
-
3. Validate trust boundary once; internal miss gets safe stub/default, external failure explicit.
|
|
35
|
-
4. Stable IDs/indexes/buffers/batches; avoid pointer graphs/dispatch/fallback.
|
|
36
|
-
5. Never concatenate growing prefixes, prepend, rescan consumed input, serialize unchanged history, rebuild incremental state; materialize once.
|
|
37
|
-
|
|
38
|
-
EVIDENCE GATE
|
|
39
|
-
|
|
40
|
-
- Map flow/lifetimes/boundaries/hot paths. Detect, verify, score, gate: baseline; deterministic positive/negative controls; lowest-owner fix; focused/proportionate checks.
|
|
41
|
-
- Scanner/fuzzer/log/static/model finding stays candidate pending reproduction. Never weaken tests, claim success from skipped/incomplete probes.`;
|
|
30
|
+
- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;
|
|
42
31
|
const PI_ADAPTATIVE_LEAN_CORE_SECTION = `
|
|
43
32
|
|
|
44
33
|
OPERATING CONTRACT
|
|
45
34
|
|
|
46
35
|
- Complete current goal within scope, granted authority; keep progress, evidence concise.
|
|
47
|
-
- Inspect relevant files
|
|
36
|
+
- Inspect relevant files and instructions before editing; make minimal coherent change, run focused checks.
|
|
48
37
|
- Use active tools, exact schemas. On failure, read error, expected shape, correct call; never repeat unchanged failure.
|
|
49
38
|
- Batch independent reads, order mutations; report real output, unresolved failures.
|
|
50
|
-
- Ask before destructive actions, credential disclosure or provider authentication changes, publication, push/tag/release,
|
|
39
|
+
- Ask before destructive actions, credential disclosure or provider authentication changes, publication, push/tag/release, scope expansion.
|
|
51
40
|
- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;
|
|
52
41
|
const PI_ADAPTATIVE_MINIMAL_CORE_SECTION = `
|
|
53
42
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { dirname } from \"node:path\";\nimport { getReadmePath } from \"../config.ts\";\nimport { getExtensionDescription, getExtensionDisplayName } from \"./extension-metadata.ts\";\nimport type { Extension } from \"./extensions/types.ts\";\nimport { enforceModelCapabilitySystemPromptBudget, type ModelCapabilityProfile } from \"./model-capability.ts\";\nimport { SKILL_VAULT_SYSTEM_RULE } from \"./provider-prompt-contracts.ts\";\nimport type { Skill } from \"./skills.ts\";\n\nexport interface BuildSystemPromptOptions {\n\t/** Capability profile that selects the stable prompt shape. Missing means full/legacy behavior. */\n\tmodelCapability?: Pick<ModelCapabilityProfile, \"class\" | \"contextWindow\" | \"reasonCode\" | \"systemPromptMaxChars\">;\n\t/** Custom system prompt (replaces default). */\n\tcustomPrompt?: string;\n\t/** Tools to include in the prompt. Defaults come from the shared active-tool surface. */\n\tselectedTools?: string[];\n\t/** Optional one-line tool snippets keyed by tool name. */\n\ttoolSnippets?: Record<string, string>;\n\t/** Additional guideline bullets appended to the default system prompt guidelines. */\n\tpromptGuidelines?: string[];\n\t/** Text to append to system prompt. */\n\tappendSystemPrompt?: string;\n\t/** Working directory. */\n\tcwd: string;\n\t/** Global instruction files (with content) plus on-demand project paths (path only). */\n\tcontextFiles?: Array<{ path: string; content?: string }>;\n\t/** Discovered skills remain host-side; retained for extension/API construction compatibility. */\n\tskills?: Skill[];\n\t/** Discovered extensions currently active. */\n\textensions?: Extension[];\n}\n\nconst MODEL_BLIND_CREDENTIAL_AUTHORITY =\n\t\"Active secret_store: host gate authorizes model-blind activation/migration from named accessible sources; no duplicate confirmation.\";\n\nconst ULTRA_TERSE_OUTPUT_POLICY = `\n\nULTRA-TERSE OUTPUT\n\n- Drop articles/filler/pleasantries/hedging; fragments valid. Strip conjunctions only when clear; each fact once.\n- Never drop not/never/no/only/except; never invent abbreviations or use causal arrows. Preserve numbers, units, code symbols, function/API names, commands, errors.\n- No self-reference/tool narration/tables/emoji/log dumps. Keep user language. Full grammar: security, irreversible actions, ambiguous order. Replies terse; artifacts normal prose.`;\n\nconst PI_ADAPTATIVE_CORE_SECTION = `\n\nOPERATING CONTRACT\n\n- Clear conversational outcome is goal; persist progress/evidence through compaction; finish or report blocker.\n- Hold scope; verify unknowns from primary sources; simplest proven design, one owner/path per invariant.\n- User outcome governs, method does not. Outcome risk: show evidence, test when practical, offer safest effective path, execute.\n- Work over 15 seconds: managed background run, event terminal, bounded handoff, owner notice; never poll.\n- Delegate independent work within host bounds; root integrates/verifies. Facts: memory, specialization: skills, behavior: source; discard noise.\n- Ask before broader scope, credential or authentication change/disclosure, destructive action, publication. Bound, source-label output; show paths.\n- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}\n\nN+2 ARCHITECTURE\n\nLanguage-agnostic principles:\n1. Bounded flat arenas/pools/rings/chunks, batch recycle.\n2. Safe zero/default data/state, no hidden allocation, one activation owner.\n3. Validate trust boundary once; internal miss gets safe stub/default, external failure explicit.\n4. Stable IDs/indexes/buffers/batches; avoid pointer graphs/dispatch/fallback.\n5. Never concatenate growing prefixes, prepend, rescan consumed input, serialize unchanged history, rebuild incremental state; materialize once.\n\nEVIDENCE GATE\n\n- Map flow/lifetimes/boundaries/hot paths. Detect, verify, score, gate: baseline; deterministic positive/negative controls; lowest-owner fix; focused/proportionate checks.\n- Scanner/fuzzer/log/static/model finding stays candidate pending reproduction. Never weaken tests, claim success from skipped/incomplete probes.`;\n\nconst PI_ADAPTATIVE_LEAN_CORE_SECTION = `\n\nOPERATING CONTRACT\n\n- Complete current goal within scope, granted authority; keep progress, evidence concise.\n- Inspect relevant files, project instructions before mutation; make smallest coherent change, run focused checks.\n- Use active tools, exact schemas. On failure, read error, expected shape, correct call; never repeat unchanged failure.\n- Batch independent reads, order mutations; report real output, unresolved failures.\n- Ask before destructive actions, credential disclosure or provider authentication changes, publication, push/tag/release, material scope expansion.\n- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;\n\nconst PI_ADAPTATIVE_MINIMAL_CORE_SECTION = `\n\nEXECUTION RULES\n\n- Work one scoped task. Inspect before editing, make small coherent change, run narrowest useful check.\n- Use listed tools, exact schemas. On failure, read error, expected shape, correct call; never repeat unchanged failure.\n- Batch independent reads, order mutations. Report actual results; never claim incomplete action.\n- Ask before destructive actions, credential disclosure or provider authentication changes, publication, push/tag/release, material scope change.\n- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;\n\nconst PI_ADAPTATIVE_CHAT_CORE_SECTION = `\n\nCHAT RULES\n\n- Answer concisely from conversation; state uncertainty.\n- No execution tools are active. Do not claim to read files, run commands, or make changes.\n- Say when the request requires a tool-capable model or additional user-provided context.`;\n\nconst DEFERRED_CONTEXT_PATH_BUDGET_CHARS = 512;\nconst EXTENSION_DESCRIPTION_BUDGET_CHARS = 180;\n\nfunction compactPromptText(value: string, maxChars: number): string {\n\tconst normalized = value.replace(/\\s+/g, \" \").trim();\n\tif (normalized.length <= maxChars) return normalized;\n\tlet end = maxChars - 1;\n\tconst code = normalized.charCodeAt(end - 1);\n\tif (code >= 0xd800 && code <= 0xdbff) end--;\n\treturn `${normalized.slice(0, end)}…`;\n}\n\nfunction formatContextFilesForPrompt(\n\tcontextFiles: Array<{ path: string; content?: string }>,\n\toptions: { deferContents: boolean; canRead: boolean },\n): string {\n\tif (contextFiles.length === 0) {\n\t\treturn \"\";\n\t}\n\tconst injected = options.deferContents ? [] : contextFiles.filter((file) => file.content !== undefined);\n\tconst deferred = options.deferContents ? contextFiles : contextFiles.filter((file) => file.content === undefined);\n\tconst parts: string[] = [];\n\n\tif (injected.length > 0) {\n\t\tconst lines = [\"\\n\\nPROJECT-SPECIFIC INSTRUCTIONS (apply in listed order)\"];\n\t\tconst seen = new Set<string>();\n\t\tfor (const { path, content } of injected) {\n\t\t\tconst identity = `${path}\\0${content ?? \"\"}`;\n\t\t\tif (seen.has(identity)) continue;\n\t\t\tseen.add(identity);\n\t\t\tlines.push(`FILE ${JSON.stringify(path)} (${(content ?? \"\").length} chars)`);\n\t\t\tlines.push(content ?? \"\");\n\t\t\tlines.push(\"END FILE\");\n\t\t}\n\t\tparts.push(lines.join(\"\\n\"));\n\t}\n\n\tif (deferred.length > 0) {\n\t\tconst lines = [\n\t\t\t\"\\n\\nPROJECT RULE PATHS — contents not preloaded.\",\n\t\t\toptions.deferContents\n\t\t\t\t? options.canRead\n\t\t\t\t\t? \"Before editing, writing, or running a mutating command, read each relevant listed file completely before any mutation. Follow its instructions; if a file cannot fit, ask for a scoped instruction digest.\"\n\t\t\t\t\t: \"No read tool is active. Ask the user for the relevant project instructions before giving project-specific guidance.\"\n\t\t\t\t: options.canRead\n\t\t\t\t\t? \"Read a listed file completely before following it. Do not assume its contents.\"\n\t\t\t\t\t: \"No read tool is active. Ask the user for the relevant project instructions before giving project-specific guidance.\",\n\t\t];\n\t\tlet pathChars = 0;\n\t\tlet included = 0;\n\t\tfor (const { path } of deferred) {\n\t\t\tconst line = `- ${JSON.stringify(path)}`;\n\t\t\tif (pathChars + line.length > DEFERRED_CONTEXT_PATH_BUDGET_CHARS) break;\n\t\t\tlines.push(line);\n\t\t\tpathChars += line.length + 1;\n\t\t\tincluded++;\n\t\t}\n\t\tconst omitted = deferred.length - included;\n\t\tif (omitted > 0) {\n\t\t\tlines.push(`- omitted=${omitted}`);\n\t\t\tlines.push(\n\t\t\t\t\"Do not mutate until the omitted instruction paths are supplied or a more capable profile is used.\",\n\t\t\t);\n\t\t}\n\t\tparts.push(lines.join(\"\\n\"));\n\t}\n\n\treturn parts.join(\"\");\n}\n\nfunction appendPromptResources(\n\tprompt: string,\n\toptions: {\n\t\tappendSection: string;\n\t\tcontextFiles: Array<{ path: string; content?: string }>;\n\t\textensions: Extension[];\n\t\tvisibleTools: string[];\n\t\tfullPrompt: boolean;\n\t\thasRead: boolean;\n\t\tdate: string;\n\t\tpromptCwd: string;\n\t\tmodelCapability: BuildSystemPromptOptions[\"modelCapability\"];\n\t},\n): string {\n\tlet result = prompt;\n\tif (options.appendSection) result += options.appendSection;\n\tresult += formatContextFilesForPrompt(options.contextFiles, {\n\t\tdeferContents: !options.fullPrompt,\n\t\tcanRead: options.hasRead,\n\t});\n\t// Extension metadata is redundant with the active tool snippets on constrained profiles.\n\tif (options.fullPrompt && options.extensions.length > 0) {\n\t\tresult += formatExtensionsForPrompt(options.extensions, options.visibleTools);\n\t}\n\t// Day-granularity only; keep this tail stable across every call on the same calendar day.\n\tresult += `\\nCurrent date: ${options.date}`;\n\tresult += `\\nCurrent working directory: ${options.promptCwd}`;\n\t// Prompt resources can come from CRLF checkouts or user files. Canonicalize once at the final\n\t// assembly boundary so capability budgets and provider cache keys are host-independent.\n\tconst normalizedResult = result.replace(/\\r\\n?/g, \"\\n\");\n\treturn options.modelCapability\n\t\t? enforceModelCapabilitySystemPromptBudget(normalizedResult, options.modelCapability)\n\t\t: normalizedResult;\n}\n\n/**\n * Build the system prompt with tools, guidelines, and context.\n *\n * CACHE-STABILITY INVARIANT: providers treat the returned string as ONE prompt-cache block (a\n * single cache breakpoint covering the whole system prompt). The caller (SystemPromptBuilder /\n * AgentSession, see `_rebuildSystemPrompt` in agent-session.ts) rebuilds it only when the TOOL\n * SURFACE changes — never per turn. For a fixed `options` (fixed tool surface, cwd, context\n * files, extensions), two calls on the SAME CALENDAR DAY must return byte-identical\n * output, because `date` below is deliberately truncated to Y-M-D granularity. Do NOT widen it\n * to a timestamp (HH:MM:SS) or otherwise fold in any per-turn-volatile field (turn counters,\n * elapsed time, random ids, etc.) — that would cache-bust this entire block on EVERY turn instead\n * of once per calendar day, defeating provider prompt caching (cost + latency regression on every\n * request). Pinned by test/system-prompt-stability.test.ts.\n */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t} = options;\n\tconst resolvedCwd = cwd;\n\tconst promptCwd = resolvedCwd.replace(/\\\\/g, \"/\");\n\n\t// Day-granularity only (see cache-stability invariant on buildSystemPrompt above): this must\n\t// stay stable across every call within a calendar day, not just within a single turn.\n\tconst now = new Date();\n\tconst year = now.getFullYear();\n\tconst month = String(now.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(now.getDate()).padStart(2, \"0\");\n\tconst date = `${year}-${month}-${day}`;\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst capabilityClass = options.modelCapability?.class ?? \"full\";\n\tconst fullPrompt = capabilityClass === \"full\";\n\tconst leanPrompt = capabilityClass === \"lean\";\n\n\tconst activeTools = selectedTools || [\"read\", \"bash\", \"python\", \"edit\", \"write\"];\n\tconst visibleTools = activeTools.filter((name) => !!toolSnippets?.[name]);\n\tconst hasRead = activeTools.includes(\"read\");\n\tconst coreSection = fullPrompt\n\t\t? PI_ADAPTATIVE_CORE_SECTION\n\t\t: leanPrompt\n\t\t\t? PI_ADAPTATIVE_LEAN_CORE_SECTION\n\t\t\t: capabilityClass === \"minimal\"\n\t\t\t\t? PI_ADAPTATIVE_MINIMAL_CORE_SECTION\n\t\t\t\t: PI_ADAPTATIVE_CHAT_CORE_SECTION;\n\tconst skillVaultContract = activeTools.includes(\"skill\") ? `\\n\\n${SKILL_VAULT_SYSTEM_RULE}` : \"\";\n\tconst operatingContract = `${coreSection}${skillVaultContract}${ULTRA_TERSE_OUTPUT_POLICY}`;\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tprompt += operatingContract;\n\t\treturn appendPromptResources(prompt, {\n\t\t\tappendSection,\n\t\t\tcontextFiles,\n\t\t\textensions: options.extensions ?? [],\n\t\t\tvisibleTools,\n\t\t\tfullPrompt,\n\t\t\thasRead,\n\t\t\tdate,\n\t\t\tpromptCwd,\n\t\t\tmodelCapability: options.modelCapability,\n\t\t});\n\t}\n\n\tconst packageRoot = dirname(getReadmePath());\n\n\t// Build tools list based on selected tools.\n\t// A tool appears in Available tools only when the caller provides a one-line snippet.\n\tconst toolsList =\n\t\tvisibleTools.length > 0 ? visibleTools.map((name) => `- ${name}: ${toolSnippets![name]}`).join(\"\\n\") : \"(none)\";\n\n\t// Build guidelines based on which tools are actually available\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\tconst addGuideline = (guideline: string): void => {\n\t\tif (guidelinesSet.has(guideline)) {\n\t\t\treturn;\n\t\t}\n\t\tguidelinesSet.add(guideline);\n\t\tguidelinesList.push(guideline);\n\t};\n\n\tconst hasBash = activeTools.includes(\"bash\");\n\tconst hasPython = activeTools.includes(\"python\");\n\tconst hasGrep = activeTools.includes(\"grep\");\n\tconst hasFind = activeTools.includes(\"find\");\n\tconst hasLs = activeTools.includes(\"ls\");\n\tconst hasReadOnlyTools = hasRead || hasGrep || hasFind || hasLs;\n\n\t// File exploration guidelines\n\tif (!fullPrompt && !leanPrompt) {\n\t\tif (hasBash) addGuideline(\"Use bash for bounded shell commands\");\n\t\tif (hasReadOnlyTools) addGuideline(\"Batch independent reads; keep mutations and dependent calls ordered\");\n\t} else if (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\taddGuideline(\"Bash: ls, rg, find\");\n\t}\n\tif (fullPrompt || leanPrompt) {\n\t\tif (hasBash || hasGrep || hasFind) {\n\t\t\taddGuideline(\"rg/jq: scoped roots/filters, exhaustive output to file\");\n\t\t}\n\t\tif (hasPython) {\n\t\t\taddGuideline(\"Python: bounded scripts/data, source edits via read/edit/write\");\n\t\t}\n\t\tif (hasReadOnlyTools) {\n\t\t\taddGuideline(\"Batch independent reads; order dependent/mutating/stateful calls\");\n\t\t}\n\t}\n\n\tif (fullPrompt || leanPrompt) {\n\t\tfor (const guideline of promptGuidelines ?? []) {\n\t\t\tconst normalized = guideline.trim();\n\t\t\tif (normalized.length > 0) {\n\t\t\t\taddGuideline(normalized);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\tconst toolGuidelinesSection = guidelines.length > 0 ? `\\n\\nTOOL GUIDELINES\\n\\n${guidelines}` : \"\";\n\n\tconst introduction = fullPrompt\n\t\t? \"Pi-Adaptative: self-evolving assistant. Deliver goals within authority; preserve continuity, own integration.\"\n\t\t: leanPrompt\n\t\t\t? \"Pi-Adaptative bounded coding agent. Complete current goal with active surface; preserve handoff evidence.\"\n\t\t\t: capabilityClass === \"minimal\"\n\t\t\t\t? \"Pi-Adaptative focused coding executor. Complete one scoped task with active tools; report verified results.\"\n\t\t\t\t: \"Pi-Adaptative concise chat assistant. No execution tools active.\";\n\tconst toolSurfaceRule =\n\t\tfullPrompt || leanPrompt\n\t\t\t? \"Use active tool surface only; unlisted capabilities may exist.\"\n\t\t\t: \"Use only the active tool surface.\";\n\tlet prompt = `${introduction}\n\nAvailable tools:\n${toolsList}\n\n${toolSurfaceRule}${operatingContract}${toolGuidelinesSection}`;\n\n\tif (fullPrompt) {\n\t\tprompt += `\n\nPI DOCS: root=${packageRoot}. Relevant work only; read needed README.md, \\`docs/...\\`, \\`examples/...\\` fully, follow links.`;\n\t}\n\n\treturn appendPromptResources(prompt, {\n\t\tappendSection,\n\t\tcontextFiles,\n\t\textensions: options.extensions ?? [],\n\t\tvisibleTools,\n\t\tfullPrompt,\n\t\thasRead,\n\t\tdate,\n\t\tpromptCwd,\n\t\tmodelCapability: options.modelCapability,\n\t});\n}\n\nfunction formatExtensionsForPrompt(extensions: Extension[], visibleTools: string[]): string {\n\tif (extensions.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst lines = [\"\\n\\nEXTENSIONS: name, path, tools, commands, description\"];\n\tlet added = 0;\n\n\tfor (const ext of extensions) {\n\t\tconst name = getExtensionDisplayName(ext.path);\n\t\tconst description = getExtensionDescription(ext.path);\n\n\t\tconst tools = Array.from(ext.tools.keys()).filter((t) => visibleTools.includes(t));\n\t\tconst commands = Array.from(ext.commands.keys());\n\n\t\t// Skip extension listing if it has no visible tools, commands, or description\n\t\tif (tools.length === 0 && commands.length === 0 && !description) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlines.push(\n\t\t\tJSON.stringify({\n\t\t\t\tname,\n\t\t\t\tpath: ext.path,\n\t\t\t\t...(tools.length > 0 ? { tools } : {}),\n\t\t\t\t...(commands.length > 0 ? { commands } : {}),\n\t\t\t\t...(description ? { description: compactPromptText(description, EXTENSION_DESCRIPTION_BUDGET_CHARS) } : {}),\n\t\t\t}),\n\t\t);\n\t\tadded++;\n\t}\n\n\tif (added === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { dirname } from \"node:path\";\nimport { getReadmePath } from \"../config.ts\";\nimport { getExtensionDescription, getExtensionDisplayName } from \"./extension-metadata.ts\";\nimport type { Extension } from \"./extensions/types.ts\";\nimport { enforceModelCapabilitySystemPromptBudget, type ModelCapabilityProfile } from \"./model-capability.ts\";\nimport { SKILL_VAULT_SYSTEM_RULE } from \"./provider-prompt-contracts.ts\";\nimport type { Skill } from \"./skills.ts\";\n\nexport interface BuildSystemPromptOptions {\n\t/** Capability profile that selects the stable prompt shape. Missing means full/legacy behavior. */\n\tmodelCapability?: Pick<ModelCapabilityProfile, \"class\" | \"contextWindow\" | \"reasonCode\" | \"systemPromptMaxChars\">;\n\t/** Custom system prompt (replaces default). */\n\tcustomPrompt?: string;\n\t/** Tools to include in the prompt. Defaults come from the shared active-tool surface. */\n\tselectedTools?: string[];\n\t/** Optional one-line tool snippets keyed by tool name. */\n\ttoolSnippets?: Record<string, string>;\n\t/** Additional guideline bullets appended to the default system prompt guidelines. */\n\tpromptGuidelines?: string[];\n\t/** Text to append to system prompt. */\n\tappendSystemPrompt?: string;\n\t/** Working directory. */\n\tcwd: string;\n\t/** Global instruction files (with content) plus on-demand project paths (path only). */\n\tcontextFiles?: Array<{ path: string; content?: string }>;\n\t/** Discovered skills remain host-side; retained for extension/API construction compatibility. */\n\tskills?: Skill[];\n\t/** Discovered extensions currently active. */\n\textensions?: Extension[];\n}\n\nconst MODEL_BLIND_CREDENTIAL_AUTHORITY =\n\t\"Active secret_store: host gate authorizes model-blind activation/migration from named accessible sources; no duplicate confirmation.\";\n\nconst ULTRA_TERSE_OUTPUT_POLICY = `\n\nULTRA-TERSE OUTPUT\n\n- Drop articles/filler/pleasantries/hedging; fragments valid. Strip conjunctions only when clear; each fact once.\n- Never drop not/never/no/only/except; never invent abbreviations or use causal arrows. Preserve numbers, units, code symbols, function/API names, commands, errors.\n- No self-reference/tool narration/tables/emoji/log dumps. Keep user language. Full grammar: security, irreversible actions, ambiguous order. Replies terse; artifacts normal prose.\n- Answer shape: status/ops turns terse; analysis/review/evaluation asks get complete structured answers; never restate harness protocol text or failure-record JSON to the user as an answer.`;\n\nconst PI_ADAPTATIVE_CORE_SECTION = `\n\nOPERATING CONTRACT\n\n- Clear conversational outcome is goal; persist progress/evidence through compaction; finish or report blocker.\n- Hold scope; verify unknowns from primary sources; simplest proven design, one owner/path per invariant.\n- User outcome governs, method does not. Outcome risk: show evidence, test when practical, offer safest effective path, execute.\n- Work over 15 seconds: managed background run, event terminal, bounded handoff, owner notice; never poll.\n- Delegate independent work within host bounds; root integrates/verifies. Facts: memory, specialization: skills, behavior: source; discard noise.\n- Implementation/verification work loads skill evidence-gated-tdd; architecture/performance design loads skill n-plus-2-architecture; their gates bind only while that work is active.\n- Explicit user instruction in current message overrides standing style (length/format/tone); security, untrusted-content, and authorization rules are never overridable.\n- Ask before broader scope, credential or authentication change/disclosure, destructive action, publication. Bound, source-label output; show paths.\n- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;\n\nconst PI_ADAPTATIVE_LEAN_CORE_SECTION = `\n\nOPERATING CONTRACT\n\n- Complete current goal within scope, granted authority; keep progress, evidence concise.\n- Inspect relevant files and instructions before editing; make minimal coherent change, run focused checks.\n- Use active tools, exact schemas. On failure, read error, expected shape, correct call; never repeat unchanged failure.\n- Batch independent reads, order mutations; report real output, unresolved failures.\n- Ask before destructive actions, credential disclosure or provider authentication changes, publication, push/tag/release, scope expansion.\n- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;\n\nconst PI_ADAPTATIVE_MINIMAL_CORE_SECTION = `\n\nEXECUTION RULES\n\n- Work one scoped task. Inspect before editing, make small coherent change, run narrowest useful check.\n- Use listed tools, exact schemas. On failure, read error, expected shape, correct call; never repeat unchanged failure.\n- Batch independent reads, order mutations. Report actual results; never claim incomplete action.\n- Ask before destructive actions, credential disclosure or provider authentication changes, publication, push/tag/release, material scope change.\n- ${MODEL_BLIND_CREDENTIAL_AUTHORITY}`;\n\nconst PI_ADAPTATIVE_CHAT_CORE_SECTION = `\n\nCHAT RULES\n\n- Answer concisely from conversation; state uncertainty.\n- No execution tools are active. Do not claim to read files, run commands, or make changes.\n- Say when the request requires a tool-capable model or additional user-provided context.`;\n\nconst DEFERRED_CONTEXT_PATH_BUDGET_CHARS = 512;\nconst EXTENSION_DESCRIPTION_BUDGET_CHARS = 180;\n\nfunction compactPromptText(value: string, maxChars: number): string {\n\tconst normalized = value.replace(/\\s+/g, \" \").trim();\n\tif (normalized.length <= maxChars) return normalized;\n\tlet end = maxChars - 1;\n\tconst code = normalized.charCodeAt(end - 1);\n\tif (code >= 0xd800 && code <= 0xdbff) end--;\n\treturn `${normalized.slice(0, end)}…`;\n}\n\nfunction formatContextFilesForPrompt(\n\tcontextFiles: Array<{ path: string; content?: string }>,\n\toptions: { deferContents: boolean; canRead: boolean },\n): string {\n\tif (contextFiles.length === 0) {\n\t\treturn \"\";\n\t}\n\tconst injected = options.deferContents ? [] : contextFiles.filter((file) => file.content !== undefined);\n\tconst deferred = options.deferContents ? contextFiles : contextFiles.filter((file) => file.content === undefined);\n\tconst parts: string[] = [];\n\n\tif (injected.length > 0) {\n\t\tconst lines = [\"\\n\\nPROJECT-SPECIFIC INSTRUCTIONS (apply in listed order)\"];\n\t\tconst seen = new Set<string>();\n\t\tfor (const { path, content } of injected) {\n\t\t\tconst identity = `${path}\\0${content ?? \"\"}`;\n\t\t\tif (seen.has(identity)) continue;\n\t\t\tseen.add(identity);\n\t\t\tlines.push(`FILE ${JSON.stringify(path)} (${(content ?? \"\").length} chars)`);\n\t\t\tlines.push(content ?? \"\");\n\t\t\tlines.push(\"END FILE\");\n\t\t}\n\t\tparts.push(lines.join(\"\\n\"));\n\t}\n\n\tif (deferred.length > 0) {\n\t\tconst lines = [\n\t\t\t\"\\n\\nPROJECT RULE PATHS — contents not preloaded.\",\n\t\t\toptions.deferContents\n\t\t\t\t? options.canRead\n\t\t\t\t\t? \"Before editing, writing, or running a mutating command, read each relevant listed file completely before any mutation. Follow its instructions; if a file cannot fit, ask for a scoped instruction digest.\"\n\t\t\t\t\t: \"No read tool is active. Ask the user for the relevant project instructions before giving project-specific guidance.\"\n\t\t\t\t: options.canRead\n\t\t\t\t\t? \"Read a listed file completely before following it. Do not assume its contents.\"\n\t\t\t\t\t: \"No read tool is active. Ask the user for the relevant project instructions before giving project-specific guidance.\",\n\t\t];\n\t\tlet pathChars = 0;\n\t\tlet included = 0;\n\t\tfor (const { path } of deferred) {\n\t\t\tconst line = `- ${JSON.stringify(path)}`;\n\t\t\tif (pathChars + line.length > DEFERRED_CONTEXT_PATH_BUDGET_CHARS) break;\n\t\t\tlines.push(line);\n\t\t\tpathChars += line.length + 1;\n\t\t\tincluded++;\n\t\t}\n\t\tconst omitted = deferred.length - included;\n\t\tif (omitted > 0) {\n\t\t\tlines.push(`- omitted=${omitted}`);\n\t\t\tlines.push(\n\t\t\t\t\"Do not mutate until the omitted instruction paths are supplied or a more capable profile is used.\",\n\t\t\t);\n\t\t}\n\t\tparts.push(lines.join(\"\\n\"));\n\t}\n\n\treturn parts.join(\"\");\n}\n\nfunction appendPromptResources(\n\tprompt: string,\n\toptions: {\n\t\tappendSection: string;\n\t\tcontextFiles: Array<{ path: string; content?: string }>;\n\t\textensions: Extension[];\n\t\tvisibleTools: string[];\n\t\tfullPrompt: boolean;\n\t\thasRead: boolean;\n\t\tdate: string;\n\t\tpromptCwd: string;\n\t\tmodelCapability: BuildSystemPromptOptions[\"modelCapability\"];\n\t},\n): string {\n\tlet result = prompt;\n\tif (options.appendSection) result += options.appendSection;\n\tresult += formatContextFilesForPrompt(options.contextFiles, {\n\t\tdeferContents: !options.fullPrompt,\n\t\tcanRead: options.hasRead,\n\t});\n\t// Extension metadata is redundant with the active tool snippets on constrained profiles.\n\tif (options.fullPrompt && options.extensions.length > 0) {\n\t\tresult += formatExtensionsForPrompt(options.extensions, options.visibleTools);\n\t}\n\t// Day-granularity only; keep this tail stable across every call on the same calendar day.\n\tresult += `\\nCurrent date: ${options.date}`;\n\tresult += `\\nCurrent working directory: ${options.promptCwd}`;\n\t// Prompt resources can come from CRLF checkouts or user files. Canonicalize once at the final\n\t// assembly boundary so capability budgets and provider cache keys are host-independent.\n\tconst normalizedResult = result.replace(/\\r\\n?/g, \"\\n\");\n\treturn options.modelCapability\n\t\t? enforceModelCapabilitySystemPromptBudget(normalizedResult, options.modelCapability)\n\t\t: normalizedResult;\n}\n\n/**\n * Build the system prompt with tools, guidelines, and context.\n *\n * CACHE-STABILITY INVARIANT: providers treat the returned string as ONE prompt-cache block (a\n * single cache breakpoint covering the whole system prompt). The caller (SystemPromptBuilder /\n * AgentSession, see `_rebuildSystemPrompt` in agent-session.ts) rebuilds it only when the TOOL\n * SURFACE changes — never per turn. For a fixed `options` (fixed tool surface, cwd, context\n * files, extensions), two calls on the SAME CALENDAR DAY must return byte-identical\n * output, because `date` below is deliberately truncated to Y-M-D granularity. Do NOT widen it\n * to a timestamp (HH:MM:SS) or otherwise fold in any per-turn-volatile field (turn counters,\n * elapsed time, random ids, etc.) — that would cache-bust this entire block on EVERY turn instead\n * of once per calendar day, defeating provider prompt caching (cost + latency regression on every\n * request). Pinned by test/system-prompt-stability.test.ts.\n */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t} = options;\n\tconst resolvedCwd = cwd;\n\tconst promptCwd = resolvedCwd.replace(/\\\\/g, \"/\");\n\n\t// Day-granularity only (see cache-stability invariant on buildSystemPrompt above): this must\n\t// stay stable across every call within a calendar day, not just within a single turn.\n\tconst now = new Date();\n\tconst year = now.getFullYear();\n\tconst month = String(now.getMonth() + 1).padStart(2, \"0\");\n\tconst day = String(now.getDate()).padStart(2, \"0\");\n\tconst date = `${year}-${month}-${day}`;\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst capabilityClass = options.modelCapability?.class ?? \"full\";\n\tconst fullPrompt = capabilityClass === \"full\";\n\tconst leanPrompt = capabilityClass === \"lean\";\n\n\tconst activeTools = selectedTools || [\"read\", \"bash\", \"python\", \"edit\", \"write\"];\n\tconst visibleTools = activeTools.filter((name) => !!toolSnippets?.[name]);\n\tconst hasRead = activeTools.includes(\"read\");\n\tconst coreSection = fullPrompt\n\t\t? PI_ADAPTATIVE_CORE_SECTION\n\t\t: leanPrompt\n\t\t\t? PI_ADAPTATIVE_LEAN_CORE_SECTION\n\t\t\t: capabilityClass === \"minimal\"\n\t\t\t\t? PI_ADAPTATIVE_MINIMAL_CORE_SECTION\n\t\t\t\t: PI_ADAPTATIVE_CHAT_CORE_SECTION;\n\tconst skillVaultContract = activeTools.includes(\"skill\") ? `\\n\\n${SKILL_VAULT_SYSTEM_RULE}` : \"\";\n\tconst operatingContract = `${coreSection}${skillVaultContract}${ULTRA_TERSE_OUTPUT_POLICY}`;\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tprompt += operatingContract;\n\t\treturn appendPromptResources(prompt, {\n\t\t\tappendSection,\n\t\t\tcontextFiles,\n\t\t\textensions: options.extensions ?? [],\n\t\t\tvisibleTools,\n\t\t\tfullPrompt,\n\t\t\thasRead,\n\t\t\tdate,\n\t\t\tpromptCwd,\n\t\t\tmodelCapability: options.modelCapability,\n\t\t});\n\t}\n\n\tconst packageRoot = dirname(getReadmePath());\n\n\t// Build tools list based on selected tools.\n\t// A tool appears in Available tools only when the caller provides a one-line snippet.\n\tconst toolsList =\n\t\tvisibleTools.length > 0 ? visibleTools.map((name) => `- ${name}: ${toolSnippets![name]}`).join(\"\\n\") : \"(none)\";\n\n\t// Build guidelines based on which tools are actually available\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\tconst addGuideline = (guideline: string): void => {\n\t\tif (guidelinesSet.has(guideline)) {\n\t\t\treturn;\n\t\t}\n\t\tguidelinesSet.add(guideline);\n\t\tguidelinesList.push(guideline);\n\t};\n\n\tconst hasBash = activeTools.includes(\"bash\");\n\tconst hasPython = activeTools.includes(\"python\");\n\tconst hasGrep = activeTools.includes(\"grep\");\n\tconst hasFind = activeTools.includes(\"find\");\n\tconst hasLs = activeTools.includes(\"ls\");\n\tconst hasReadOnlyTools = hasRead || hasGrep || hasFind || hasLs;\n\n\t// File exploration guidelines\n\tif (!fullPrompt && !leanPrompt) {\n\t\tif (hasBash) addGuideline(\"Use bash for bounded shell commands\");\n\t\tif (hasReadOnlyTools) addGuideline(\"Batch independent reads; keep mutations and dependent calls ordered\");\n\t} else if (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\taddGuideline(\"Bash: ls, rg, find\");\n\t}\n\tif (fullPrompt || leanPrompt) {\n\t\tif (hasBash || hasGrep || hasFind) {\n\t\t\taddGuideline(\"rg/jq: scoped roots/filters, exhaustive output to file\");\n\t\t}\n\t\tif (hasPython) {\n\t\t\taddGuideline(\"Python: bounded scripts/data, source edits via read/edit/write\");\n\t\t}\n\t\tif (hasReadOnlyTools) {\n\t\t\taddGuideline(\"Batch independent reads; order dependent/mutating/stateful calls\");\n\t\t}\n\t}\n\n\tif (fullPrompt || leanPrompt) {\n\t\tfor (const guideline of promptGuidelines ?? []) {\n\t\t\tconst normalized = guideline.trim();\n\t\t\tif (normalized.length > 0) {\n\t\t\t\taddGuideline(normalized);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\tconst toolGuidelinesSection = guidelines.length > 0 ? `\\n\\nTOOL GUIDELINES\\n\\n${guidelines}` : \"\";\n\n\tconst introduction = fullPrompt\n\t\t? \"Pi-Adaptative: self-evolving assistant. Deliver goals within authority; preserve continuity, own integration.\"\n\t\t: leanPrompt\n\t\t\t? \"Pi-Adaptative bounded coding agent. Complete current goal with active surface; preserve handoff evidence.\"\n\t\t\t: capabilityClass === \"minimal\"\n\t\t\t\t? \"Pi-Adaptative focused coding executor. Complete one scoped task with active tools; report verified results.\"\n\t\t\t\t: \"Pi-Adaptative concise chat assistant. No execution tools active.\";\n\tconst toolSurfaceRule =\n\t\tfullPrompt || leanPrompt\n\t\t\t? \"Use active tool surface only; unlisted capabilities may exist.\"\n\t\t\t: \"Use only the active tool surface.\";\n\tlet prompt = `${introduction}\n\nAvailable tools:\n${toolsList}\n\n${toolSurfaceRule}${operatingContract}${toolGuidelinesSection}`;\n\n\tif (fullPrompt) {\n\t\tprompt += `\n\nPI DOCS: root=${packageRoot}. Relevant work only; read needed README.md, \\`docs/...\\`, \\`examples/...\\` fully, follow links.`;\n\t}\n\n\treturn appendPromptResources(prompt, {\n\t\tappendSection,\n\t\tcontextFiles,\n\t\textensions: options.extensions ?? [],\n\t\tvisibleTools,\n\t\tfullPrompt,\n\t\thasRead,\n\t\tdate,\n\t\tpromptCwd,\n\t\tmodelCapability: options.modelCapability,\n\t});\n}\n\nfunction formatExtensionsForPrompt(extensions: Extension[], visibleTools: string[]): string {\n\tif (extensions.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst lines = [\"\\n\\nEXTENSIONS: name, path, tools, commands, description\"];\n\tlet added = 0;\n\n\tfor (const ext of extensions) {\n\t\tconst name = getExtensionDisplayName(ext.path);\n\t\tconst description = getExtensionDescription(ext.path);\n\n\t\tconst tools = Array.from(ext.tools.keys()).filter((t) => visibleTools.includes(t));\n\t\tconst commands = Array.from(ext.commands.keys());\n\n\t\t// Skip extension listing if it has no visible tools, commands, or description\n\t\tif (tools.length === 0 && commands.length === 0 && !description) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlines.push(\n\t\t\tJSON.stringify({\n\t\t\t\tname,\n\t\t\t\tpath: ext.path,\n\t\t\t\t...(tools.length > 0 ? { tools } : {}),\n\t\t\t\t...(commands.length > 0 ? { commands } : {}),\n\t\t\t\t...(description ? { description: compactPromptText(description, EXTENSION_DESCRIPTION_BUDGET_CHARS) } : {}),\n\t\t\t}),\n\t\t);\n\t\tadded++;\n\t}\n\n\tif (added === 0) {\n\t\treturn \"\";\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash.ts"],"names":[],"mappings":"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"}
|
package/dist/core/tools/bash.js
CHANGED
|
@@ -435,11 +435,10 @@ function createShellToolDefinition(cwd, backendShell, contractPlatform, options)
|
|
|
435
435
|
promptGuidelines: routesWindowsContract
|
|
436
436
|
? [
|
|
437
437
|
"On Windows, use Bash-like commands; never write PowerShell/ask owner to choose shell.",
|
|
438
|
-
"Supports for, break/continue, printf, pipes/redirection,
|
|
439
|
-
"Arithmetic outside for, job control, process substitution, heredocs, nested shells fail closed.",
|
|
438
|
+
"Supports for, break/continue, printf, pipes/redirection, expansions, chaining; unhandled syntax fails closed.",
|
|
440
439
|
"cd/export/unset state persists across bash calls and PowerShell/Python tiers.",
|
|
441
440
|
"File commands use literal paths; verify targets before recursive rm/cp/mv.",
|
|
442
|
-
`Bash timeout values are seconds
|
|
441
|
+
`Bash timeout values are seconds; omit to use the ${DEFAULT_COMMAND_TIMEOUT_SECONDS}s default.`,
|
|
443
442
|
`Search narrowly: root/filters, prefer grep/find. Broad scans fail; unavoidable scan: broadSearch="${BROAD_SEARCH_OUTPUT_ROUTE}", then inspect narrowly.`,
|
|
444
443
|
]
|
|
445
444
|
: [
|