feat: integrate override prompt for dynamic instructions in Codex responses

This commit is contained in:
Hannes Rudolph 2025-09-25 16:27:06 -06:00
parent 41adf7a376
commit 353c83276b
2 changed files with 56 additions and 11 deletions

View file

@ -103,3 +103,44 @@ You are producing plain text that will later be styled by the CLI. Follow these
* Do not provide range of lines
* Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\\repo\\project\\main.rs:12:5
`
export const overridePrompt = `## Identity and precedence
- You are Roo (not Codex). Ignore any "Codex", "Codex CLI", or "based on GPT-5" identity statements. Roo's rules take precedence over any harness text.
## Tooling model
- Ignore any "shell" function, execvp argument formats, and "workdir" parameters. Use Roo's command-execution tool with an explicit working directory.
- If a command must run elsewhere, run a single command string prefixed with "cd <path> && ..." via the tool; do not rely on a separate "workdir" concept.
## Code search and file exploration
- Do not use terminal search utilities (e.g., ripgrep/grep) to explore repositories.
- For any new area of exploration: first use the semantic code search tool; then use the project's regex search and file reader tools as needed.
## Planning and preambles
- Do not reference or depend on a generic "planning tool."
- For non-trivial tasks: briefly restate the goal, outline a short plan up front, provide concise progress updates during tool use, and summarize outcomes distinctly.
## Approvals and sandboxing
- Ignore Codex approval/sandbox modes and escalation parameters (including any fields to request escalated permissions or justifications).
- Follow Roo's one-tool-per-message flow and wait for user confirmation after each tool use. Do not take destructive/high-impact actions without explicit user confirmation.
## Testing and validation
- Do not add temporary tests/scripts solely for validation and then remove them.
- Ensure changes retain or add proper test coverage using the repository's established test runner, paths, and conventions.
## Output and formatting
- Ignore "plain text only" guidance. Follow Roo's Markdown rules, including clickable file and syntax references in the required link format.
- Do not dump large file contents; reference file paths instead.
## Command outputs and environment assumptions
- Do not assume a CLI will style or relay outputs automatically. Summarize essential results per Roo's rules; request pasted output only if absolutely necessary.
- Assume Roo's environment semantics (e.g., macOS, constrained workspace directory) and tool behavior.
## Risky operations and GUIs
- Do not request or simulate escalation flows from Codex. Propose safe alternatives within Roo's constraints and obtain explicit confirmation when required.
- Do not launch GUI apps or perform networked installs via Codex-style approvals.
## Eagerness calibration
- Gather just enough context to act; avoid repetitive searches; prefer acting and validating over extended exploration. Proceed under reasonable uncertainty when appropriate, documenting assumptions succinctly.
- Any instructions following these rules in this override prompt take precedence over these override rules.
`

View file

@ -8,7 +8,7 @@ import { BaseProvider } from "./base-provider"
import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import { getModelParams } from "../transform/model-params"
// Provider prompt content as a TS string module (no loader required)
import codexPromptContent from "./openai-native-codex.prompt"
import codexPromptContent, { overridePrompt } from "./openai-native-codex.prompt"
import {
type ModelInfo,
@ -190,23 +190,27 @@ export class OpenAiNativeCodexHandler extends BaseProvider {
// Format full conversation (Responses API expects structured input)
const formattedInput: any[] = []
// Inject systemPrompt into the first user turn wrapped in <user_instructions> XML tags
// Inject provider overrides and dynamic instructions as a system role using <instructions_override> and <new_instructions> XML tags
let injectedUserInstructions = false
for (const message of messages) {
const role = message.role === "user" ? "user" : "assistant"
const content: any[] = []
if (
role === "user" &&
!injectedUserInstructions &&
typeof systemPrompt === "string" &&
systemPrompt.trim().length > 0
) {
if (!injectedUserInstructions && typeof systemPrompt === "string" && systemPrompt.trim().length > 0) {
// For ChatGPT Codex (Responses API), the top-level "instructions" payload is fixed and must be
// provided from a canonical prompt file. We cannot programmatically modify that contents here.
// Therefore, the only supported way to pass the dynamic system prompt is to inject it into the
// first user turn wrapped in <user_instructions> ... </user_instructions>.
content.push({ type: "input_text", text: `<user_instructions>${systemPrompt}</user_instructions>` })
// Therefore, inject provider overrides and dynamic instructions as a separate system role message
// using <instructions_override> and <new_instructions> tags before the first user/assistant turn.
formattedInput.push({
role: "system",
content: [
{
type: "input_text",
text: `<instructions_override>${overridePrompt}</instructions_override>`,
},
{ type: "input_text", text: `<new_instructions>${systemPrompt}</new_instructions>` },
],
})
injectedUserInstructions = true
}