refactor: rebuild agent system prompt

This commit is contained in:
Peter Steinberger
2026-01-08 02:20:18 +01:00
parent e9346e6cf0
commit cad853b547
7 changed files with 184 additions and 131 deletions

View File

@@ -15,7 +15,6 @@ import {
discoverModels,
SessionManager,
SettingsManager,
type Skill,
} from "@mariozechner/pi-coding-agent";
import { resolveHeartbeatPrompt } from "../auto-reply/heartbeat.js";
import type {
@@ -54,6 +53,7 @@ import {
import { ensureClawdbotModelsJson } from "./models-config.js";
import {
buildBootstrapContextFiles,
type EmbeddedContextFile,
ensureSessionHeader,
formatAssistantErrorText,
isAuthAssistantError,
@@ -85,12 +85,10 @@ import { resolveSandboxContext } from "./sandbox.js";
import {
applySkillEnvOverrides,
applySkillEnvOverridesFromSnapshot,
buildWorkspaceSkillSnapshot,
loadWorkspaceSkillEntries,
type SkillEntry,
type SkillSnapshot,
} from "./skills.js";
import { buildAgentSystemPromptAppend } from "./system-prompt.js";
import { buildAgentSystemPrompt } from "./system-prompt.js";
import { normalizeUsage, type UsageLike } from "./usage.js";
import { loadWorkspaceBootstrapFiles } from "./workspace.js";
@@ -496,7 +494,7 @@ export function buildEmbeddedSandboxInfo(
};
}
function buildEmbeddedAppendPrompt(params: {
function buildEmbeddedSystemPrompt(params: {
workspaceDir: string;
defaultThinkLevel?: ThinkLevel;
extraSystemPrompt?: string;
@@ -515,8 +513,9 @@ function buildEmbeddedAppendPrompt(params: {
modelAliasLines: string[];
userTimezone: string;
userTime?: string;
contextFiles?: EmbeddedContextFile[];
}): string {
return buildAgentSystemPromptAppend({
return buildAgentSystemPrompt({
workspaceDir: params.workspaceDir,
defaultThinkLevel: params.defaultThinkLevel,
extraSystemPrompt: params.extraSystemPrompt,
@@ -529,17 +528,15 @@ function buildEmbeddedAppendPrompt(params: {
modelAliasLines: params.modelAliasLines,
userTimezone: params.userTimezone,
userTime: params.userTime,
contextFiles: params.contextFiles,
});
}
export function createSystemPromptAppender(
appendPrompt: string,
export function createSystemPromptOverride(
systemPrompt: string,
): (defaultPrompt: string) => string {
const trimmed = appendPrompt.trim();
if (!trimmed) {
return (defaultPrompt) => defaultPrompt;
}
return (defaultPrompt) => `${defaultPrompt}\n\n${appendPrompt}`;
const trimmed = systemPrompt.trim();
return () => trimmed;
}
const BUILT_IN_TOOL_NAMES = new Set(["read", "bash", "edit", "write"]);
@@ -672,25 +669,6 @@ function resolveModel(
return { model, authStorage, modelRegistry };
}
function resolvePromptSkills(
snapshot: SkillSnapshot,
entries: SkillEntry[],
): Skill[] {
if (snapshot.resolvedSkills?.length) {
return snapshot.resolvedSkills;
}
const snapshotNames = snapshot.skills.map((entry) => entry.name);
if (snapshotNames.length === 0) return [];
const entryByName = new Map(
entries.map((entry) => [entry.skill.name, entry.skill]),
);
return snapshotNames
.map((name) => entryByName.get(name))
.filter((skill): skill is Skill => Boolean(skill));
}
export async function compactEmbeddedPiSession(params: {
sessionId: string;
sessionKey?: string;
@@ -780,12 +758,6 @@ export async function compactEmbeddedPiSession(params: {
const skillEntries = shouldLoadSkillEntries
? loadWorkspaceSkillEntries(effectiveWorkspace)
: [];
const skillsSnapshot =
params.skillsSnapshot ??
buildWorkspaceSkillSnapshot(effectiveWorkspace, {
config: params.config,
entries: skillEntries,
});
restoreSkillEnv = params.skillsSnapshot
? applySkillEnvOverridesFromSnapshot({
snapshot: params.skillsSnapshot,
@@ -799,7 +771,6 @@ export async function compactEmbeddedPiSession(params: {
const bootstrapFiles =
await loadWorkspaceBootstrapFiles(effectiveWorkspace);
const contextFiles = buildBootstrapContextFiles(bootstrapFiles);
const promptSkills = resolvePromptSkills(skillsSnapshot, skillEntries);
const tools = createClawdbotCodingTools({
bash: {
...params.config?.agent?.bash,
@@ -825,7 +796,7 @@ export async function compactEmbeddedPiSession(params: {
params.config?.agent?.userTimezone,
);
const userTime = formatUserTime(new Date(), userTimezone);
const appendPrompt = buildEmbeddedAppendPrompt({
const appendPrompt = buildEmbeddedSystemPrompt({
workspaceDir: effectiveWorkspace,
defaultThinkLevel: params.thinkLevel,
extraSystemPrompt: params.extraSystemPrompt,
@@ -840,8 +811,9 @@ export async function compactEmbeddedPiSession(params: {
modelAliasLines: buildModelAliasLines(params.config),
userTimezone,
userTime,
contextFiles,
});
const systemPrompt = createSystemPromptAppender(appendPrompt);
const systemPrompt = createSystemPromptOverride(appendPrompt);
// Pre-warm session file to bring it into OS page cache
await prewarmSessionFile(params.sessionFile);
@@ -878,8 +850,8 @@ export async function compactEmbeddedPiSession(params: {
customTools,
sessionManager,
settingsManager,
skills: promptSkills,
contextFiles,
skills: [],
contextFiles: [],
additionalExtensionPaths,
}));
@@ -1095,12 +1067,6 @@ export async function runEmbeddedPiAgent(params: {
const skillEntries = shouldLoadSkillEntries
? loadWorkspaceSkillEntries(effectiveWorkspace)
: [];
const skillsSnapshot =
params.skillsSnapshot ??
buildWorkspaceSkillSnapshot(effectiveWorkspace, {
config: params.config,
entries: skillEntries,
});
restoreSkillEnv = params.skillsSnapshot
? applySkillEnvOverridesFromSnapshot({
snapshot: params.skillsSnapshot,
@@ -1114,10 +1080,6 @@ export async function runEmbeddedPiAgent(params: {
const bootstrapFiles =
await loadWorkspaceBootstrapFiles(effectiveWorkspace);
const contextFiles = buildBootstrapContextFiles(bootstrapFiles);
const promptSkills = resolvePromptSkills(
skillsSnapshot,
skillEntries,
);
// Tool schemas must be provider-compatible (OpenAI requires top-level `type: "object"`).
// `createClawdbotCodingTools()` normalizes schemas so the session can pass them through unchanged.
const tools = createClawdbotCodingTools({
@@ -1145,7 +1107,7 @@ export async function runEmbeddedPiAgent(params: {
params.config?.agent?.userTimezone,
);
const userTime = formatUserTime(new Date(), userTimezone);
const appendPrompt = buildEmbeddedAppendPrompt({
const appendPrompt = buildEmbeddedSystemPrompt({
workspaceDir: effectiveWorkspace,
defaultThinkLevel: thinkLevel,
extraSystemPrompt: params.extraSystemPrompt,
@@ -1160,8 +1122,9 @@ export async function runEmbeddedPiAgent(params: {
modelAliasLines: buildModelAliasLines(params.config),
userTimezone,
userTime,
contextFiles,
});
const systemPrompt = createSystemPromptAppender(appendPrompt);
const systemPrompt = createSystemPromptOverride(appendPrompt);
// Pre-warm session file to bring it into OS page cache
await prewarmSessionFile(params.sessionFile);
@@ -1202,8 +1165,8 @@ export async function runEmbeddedPiAgent(params: {
customTools,
sessionManager,
settingsManager,
skills: promptSkills,
contextFiles,
skills: [],
contextFiles: [],
additionalExtensionPaths,
}));