feat(engine): mode-agnostic system prompt with append-only mode/approval messages#2687
feat(engine): mode-agnostic system prompt with append-only mode/approval messages#2687LeoAlex0 wants to merge 1 commit into
Conversation
|
Thanks @LeoAlex0 for taking the time to contribute. This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in Please read |
There was a problem hiding this comment.
Code Review
This pull request refactors system prompt handling in the TUI engine to improve prefix-cache stability (e.g., for DeepSeek) by delivering mode contracts as append-only system messages rather than inlining them into the initial system prompt. The review feedback highlights a critical bug where the system_prompt_override flag from Op::SyncSession is unconditionally ignored, which prevents synced sessions from refreshing dynamic context when intended. Additionally, the feedback suggests updating a test to properly verify prompt preservation and notes a design issue where using AppMode::Agent as the stable baseline results in duplicate or conflicting instructions for other modes.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
e26e8fd to
dd1d16b
Compare
dd1d16b to
941d931
Compare
832ec40 to
207f670
Compare
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
207f670 to
0d280fb
Compare
Move mode declarations from message[0] into append-only system messages so that message[0] stays byte-stable across mode switches. This lets existing sessions hit the DeepSeek prefix cache on the very first request after upgrade — zero-downtime cache migration. - New functions: mode_prompt_marker, mode_prompt_text, mode_prompt_system_message, latest_mode_prompt_matches, ensure_mode_prompt_message - Op::ChangeMode uses ensure_mode_prompt_message instead of refresh_system_prompt - handle_send_message calls ensure_mode_prompt_message before building the user message, so the mode declaration always appears ahead of user text - refresh_system_prompt drops its dead _mode parameter - 12 new tests covering marker/text/message construction, dedup logic, mode-switch behavior, and message[0] byte-stability
0d280fb to
37d9525
Compare
Summary / 摘要
Make
message[0]completely mode-agnostic by strippingmode_prompt(mode)andapproval_prompt_for_mode(mode, …)from the base system prompt inprompts.rs. Mode instructions and approval policies are now delivered exclusively through deduplicated append-only system messages, keepingmessage[0]byte-stable across mode switches and approval-policy changes for DeepSeek KV prefix-cache hits.将
prompts.rs中mode_prompt(mode)和approval_prompt_for_mode(mode, …)从基础系统提示中移除,使message[0]完全模式无关。模式指令与审批策略通过去重的追加式 system 消息送达,保证message[0]在模式切换和审批策略变更后字节稳定。Architecture / 架构
ensure_mode_prompt_message(mode)— appends<mode_prompt>only when mode changes。仅 mode 变更时追加<mode_prompt>ensure_approval_prompt_message(mode)— appends<approval_policy>only when approval mode changes。仅审批策略变更时追加<approval_policy>system_prompt_override: trueto freeze oldmessage[0]verbatim for upgrade-day cache hits。TUI 会话恢复使用system_prompt_override: true冻结旧message[0],保证升级当天缓存命中Scope / 改动范围
prompts.rsmode_prompt(mode)andapproval_prompt_for_mode(mode, …)/ 移除模式与审批内嵌文本engine.rsSTABLE_SYSTEM_PROMPT_MODE; addedensure_approval_prompt_message/ 移除常量,新增审批追加通道ui.rssystem_prompt_override: false→true/ 会话恢复路径改为冻结旧 prompttests.rscapacity_flow.rsturn_loop.rsops.rs,session.rsTesting / 测试
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features(0 warnings)cargo test --workspace --all-features(3955 passed, 0 failed)Checklist
Greptile Summary
This PR refactors mode and approval-policy instructions out of the stable
message[0]system prompt and into deduplicated append-only system messages, so the base prompt stays byte-identical across mode switches and enables DeepSeek KV prefix-cache hits.prompts.rs:mode_promptandapproval_prompt_for_moderemoved fromcompose_prompt_with_approval_and_model; those strings now travel as tagged<mode_prompt>/<approval_policy>system messages appended byensure_mode_prompt_message/ensure_approval_prompt_message.engine.rs:refresh_system_promptmade mode-agnostic (always builds Agent baseline); new marker/dedup helpers scan the message list in reverse to avoid duplicate appends;Op::SetModel.modeandOp::SyncSession.system_prompt_overrideare now effectively dead fields.ui.rs: AllSyncSessioncall sites flip fromsystem_prompt_override: false→true, freezing the restored prompt; since the engine gate-checkssystem_prompt.is_some(), fresh sessions are unaffected, but active sessions that hit workspace-switch or provider-switch paths will also freeze their prompt.Confidence Score: 3/5
The change is structurally sound, but the ordering of ensure_approval_prompt_message vs. the session.approval_mode assignment in handle_send_message means a user changing their approval policy in Agent mode will have the old policy silently forwarded to the model for that turn.
In handle_send_message, ensure_approval_prompt_message reads self.session.approval_mode before the incoming approval_mode parameter is written to the session (lines 1609-1613). Any in-flight policy change (e.g. Suggest to Never) is therefore invisible to the dedup check: the old policy marker still matches, no new message is appended, and the model operates under the wrong approval contract for the entire turn.
crates/tui/src/core/engine.rs — specifically the handle_send_message call site for ensure_approval_prompt_message relative to the self.session.approval_mode assignment
Important Files Changed
Sequence Diagram
sequenceDiagram participant UI participant Engine participant Session Note over Engine,Session: Op::ChangeMode UI->>Engine: "ChangeMode { mode: Yolo }" Engine->>Engine: ensure_mode_prompt_message(Yolo) Engine->>Session: add mode_prompt message Engine->>Engine: ensure_approval_prompt_message(Yolo) Engine->>Session: add approval_policy message Engine->>UI: SessionUpdated (message[0] unchanged) Note over Engine,Session: handle_send_message approval change bug UI->>Engine: "SendMessage { mode: Agent, approval_mode: Never }" Engine->>Engine: ensure_approval_prompt_message(Agent) Engine->>Engine: "reads self.session.approval_mode = Suggest (stale)" Engine->>Engine: latest matches Suggest - skips append Engine->>Session: add user message Engine->>Session: "self.session.approval_mode = Never (too late)" Engine->>Engine: refresh_system_prompt() Note over Engine,Session: after compaction Engine->>Session: "messages = compacted" Engine->>Engine: ensure_mode_prompt_message(mode) Engine->>Session: re-append mode prompt Engine->>Engine: ensure_approval_prompt_message(mode) Engine->>Session: re-append approval promptReviews (5): Last reviewed commit: "feat(cache): append mode prompts without..." | Re-trigger Greptile