Skip to content

feat(codex): allow replacing Codex's built-in base instructions - #1211

Open
gitwillsky wants to merge 1 commit into
volcengine:mainfrom
gitwillsky:feat/codex-base-instructions
Open

gitwillsky wants to merge 1 commit into
volcengine:mainfrom
gitwillsky:feat/codex-base-instructions

Conversation

@gitwillsky

Copy link
Copy Markdown

Problem

The Codex runtime always keeps Codex's built-in base system prompt (~21KB of coding-assistant guidance on apply_patch, update_plan, shell use and AGENTS.md) and sends the agent identity and instruction as developer_instructions. That is the right default, but there is no way to opt out. Agents that are not coding assistants (question answering, for example) carry guidance that does not apply to them, and it sits at the system layer above the agent's own developer instructions (tool preambles, short default answers, and so on). The Codex SDK supports replacing it natively through thread_start(base_instructions=...); VeADK just does not expose it.

Change

  • Add CodexRuntimeConfig.base_instructions: str | None = None (non-empty when set). When set, it is passed to thread_start(base_instructions=...) and replaces the built-in prompt. It applies on both transports: on direct Codex sends it as the Responses instructions, and the shim already forwards instructions.
  • The agent identity and instruction still go through developer_instructions, and the tool-availability note is still appended. The default None keeps today's behavior: base_instructions is not sent.
  • Persistent threads (thread_mode="resume") keep the base instructions they started with, so the thread instruction hash includes them when they are set. When unset, the hash is exactly the existing developer-only hash, so existing stored threads and warm processes keep resuming after the upgrade.
  • The startup log distinguishes codex_base_instructions_preserved from codex_base_instructions_replaced (lengths only, no content).
  • Docs (runtime.mdx / runtime.en.mdx): the new field in the config table, plus a short section on replacing the built-in prompt, including that personality no longer applies because it is rendered into the replaced template.

Compatibility

Additive configuration field with a default that keeps current behavior. No change to public imports or event contracts.

Verification (2026-11-05, against main @ e5bfe04)

  • New tests in tests/runtime/codex/test_codex_runtime_sdk.py: with base_instructions set, thread_start receives it and developer_instructions is unchanged, and the "replaced" log line is emitted; the thread instruction hash equals the existing hash when unset and changes when set or changed. The existing test still asserts that base_instructions is not sent by default.
  • pytest -c pytest.ini tests/runtime/codex/: 145 passed, 29 skipped (smoke/probe opt-ins), 1 failed: test_codex_runtime.py::test_tool_executor_supports_stdio_mcp_toolset, which fails identically on unmodified main in this environment (MCP stdio toolset listing fails with ConnectionError).
  • ruff@0.11.12 format --check and ruff check on the changed files: pass.
  • Environment note: run with Python 3.12 and openai-codex 0.159.2 against an installed VeADK 1.1.24 whose affected files are byte-identical to main, overlaid with this change, not a full uv sync checkout.
  • Not run: CODEX_RUN_SMOKE=1 real-binary smoke (no prepared environment here), pre-commit run --all-files (including gitleaks), the full parallel regression, and the docs site build. A real Codex run confirming that the built-in prompt is absent from the model request is the remaining check.

This PR was prepared with an AI coding agent; I authorized the submission.

🤖 Generated with Claude Code

Add CodexRuntimeConfig.base_instructions. When set, it is passed to the
Codex SDK's native thread_start(base_instructions=...) and replaces
Codex's built-in ~21KB coding-assistant system prompt, on both
transports. The default None keeps the current behavior; the agent
identity and instruction still go through developer_instructions.

Persistent threads keep the base instructions they started with, so the
thread instruction hash includes them when set (and is unchanged when
unset, so existing stored threads keep resuming).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant