← Back to PRs

#14602: fix(plugins): hook systemPrompt gets collected then thrown away (#14583)

by yinghaosang open 2026-02-12 11:10 View on GitHub →
agents stale size: S
#### Summary The `before_agent_start` plugin hook accepts a `systemPrompt` return field, and the hook runner correctly merges it from all plugins — but the reply handler in `attempt.ts` only reads `prependContext` and skips `systemPrompt` entirely. Plugins that return `systemPrompt` get no effect, forcing them to stuff everything into `prependContext` (which prepends to the user message and leaks into visible output on smaller models). This adds the missing `applySystemPromptOverrideToSession` call so `hookResult.systemPrompt` actually gets applied. Closes #14583 #13475 lobster-biscuit #### Repro Steps 1. Create a plugin that returns `{ systemPrompt: "custom instructions" }` from a `before_agent_start` hook handler 2. Send a message — the custom system prompt isn't applied; the agent uses the default system prompt #### Root Cause `attempt.ts` checks `hookResult?.prependContext` and wires it into the effective prompt, but there's no corresponding check for `hookResult?.systemPrompt`. The session's system prompt stays unchanged even when plugins return one. #### Behavior Changes - Before: `hookResult.systemPrompt` from `before_agent_start` hooks was collected and discarded - After: `hookResult.systemPrompt` gets applied to the agent session via `applySystemPromptOverrideToSession` #### Tests - `src/agents/pi-embedded-runner/system-prompt.test.ts` — covers `applySystemPromptOverrideToSession` with string overrides, whitespace trimming, function overrides, and `_rebuildSystemPrompt` wiring - build, check, directory-level tests pass **Sign-Off** - Models used: N/A - Submitter effort: traced the hook runner → attempt.ts call chain, confirmed systemPrompt was collected but never consumed, added the missing call - Agent notes: N/A <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR wires the `before_agent_start` hook’s `systemPrompt` return value into the embedded runner session by calling `applySystemPromptOverrideToSession` in `src/agents/pi-embedded-runner/run/attempt.ts`. Previously, only `prependContext` was applied to the user prompt; `systemPrompt` was merged by the hook runner but then dropped. It also adds a new Vitest file (`src/agents/pi-embedded-runner/system-prompt.test.ts`) covering `applySystemPromptOverrideToSession` behavior for string overrides (including trimming), function overrides via `createSystemPromptOverride`, and the internal `_rebuildSystemPrompt` wiring that the runner sets on the session object. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - Change is narrowly scoped: it applies an already-merged hook result field (`systemPrompt`) to the session, and the new tests exercise the override helper without altering broader runtime behavior beyond the intended bug fix. No unverified behavioral assumptions remain after tracing hook result typing and usage. - No files require special attention <!-- greptile_other_comments_section --> <sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs