mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Move memory prompt injection to app-server extension (#22841)
## Why Memory prompt injection should be owned by the extension path that app-server composes at runtime, not by an inlined special case inside `codex-core`. This keeps `codex-core` focused on session orchestration while allowing the memories extension to own its app-server prompt behavior. ## What Changed - Registers `codex-memories-extension` in the app-server extension registry. - Moves the memory developer-instruction injection out of `core/src/session/mod.rs` and into the memories extension prompt contributor. - Adds config-change handling so the extension keeps its per-thread memory settings in sync after startup. - Leaves memories read/retrieval tools unregistered for now so this PR only changes prompt injection. - Removes the stale `cargo-shear` ignore now that app-server depends on the extension crate. ## Validation Not run locally; validation is left to CI.
This commit is contained in:
Generated
+1
@@ -1907,6 +1907,7 @@ dependencies = [
|
|||||||
"codex-hooks",
|
"codex-hooks",
|
||||||
"codex-login",
|
"codex-login",
|
||||||
"codex-mcp",
|
"codex-mcp",
|
||||||
|
"codex-memories-extension",
|
||||||
"codex-memories-write",
|
"codex-memories-write",
|
||||||
"codex-model-provider",
|
"codex-model-provider",
|
||||||
"codex-model-provider-info",
|
"codex-model-provider-info",
|
||||||
|
|||||||
@@ -470,7 +470,6 @@ unwrap_used = "deny"
|
|||||||
[workspace.metadata.cargo-shear]
|
[workspace.metadata.cargo-shear]
|
||||||
ignored = [
|
ignored = [
|
||||||
"codex-agent-graph-store",
|
"codex-agent-graph-store",
|
||||||
"codex-memories-extension",
|
|
||||||
"icu_provider",
|
"icu_provider",
|
||||||
"openssl-sys",
|
"openssl-sys",
|
||||||
"codex-v8-poc",
|
"codex-v8-poc",
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ codex-backend-client = { workspace = true }
|
|||||||
codex-file-search = { workspace = true }
|
codex-file-search = { workspace = true }
|
||||||
codex-chatgpt = { workspace = true }
|
codex-chatgpt = { workspace = true }
|
||||||
codex-login = { workspace = true }
|
codex-login = { workspace = true }
|
||||||
|
codex-memories-extension = { workspace = true }
|
||||||
codex-memories-write = { workspace = true }
|
codex-memories-write = { workspace = true }
|
||||||
codex-mcp = { workspace = true }
|
codex-mcp = { workspace = true }
|
||||||
codex-model-provider = { workspace = true }
|
codex-model-provider = { workspace = true }
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ where
|
|||||||
{
|
{
|
||||||
let mut builder = ExtensionRegistryBuilder::<Config>::new();
|
let mut builder = ExtensionRegistryBuilder::<Config>::new();
|
||||||
codex_guardian::install(&mut builder, guardian_agent_spawner);
|
codex_guardian::install(&mut builder, guardian_agent_spawner);
|
||||||
|
codex_memories_extension::install(&mut builder);
|
||||||
Arc::new(builder.build())
|
Arc::new(builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2690,14 +2690,6 @@ impl Session {
|
|||||||
{
|
{
|
||||||
developer_sections.push(developer_instructions.to_string());
|
developer_sections.push(developer_instructions.to_string());
|
||||||
}
|
}
|
||||||
// Add developer instructions for memories.
|
|
||||||
if turn_context.features.enabled(Feature::MemoryTool)
|
|
||||||
&& turn_context.config.memories.use_memories
|
|
||||||
&& let Some(memory_prompt) =
|
|
||||||
build_memory_tool_developer_instructions(&turn_context.config.codex_home).await
|
|
||||||
{
|
|
||||||
developer_sections.push(memory_prompt);
|
|
||||||
}
|
|
||||||
// Add developer instructions from collaboration_mode if they exist and are non-empty
|
// Add developer instructions from collaboration_mode if they exist and are non-empty
|
||||||
if turn_context.config.include_collaboration_mode_instructions
|
if turn_context.config.include_collaboration_mode_instructions
|
||||||
&& let Some(collab_instructions) =
|
&& let Some(collab_instructions) =
|
||||||
@@ -3438,8 +3430,6 @@ pub(crate) fn emit_subagent_session_started(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
use codex_memories_read::build_memory_tool_developer_instructions;
|
|
||||||
|
|
||||||
/// Builds the hook engine for one config snapshot, including any enabled plugin hooks.
|
/// Builds the hook engine for one config snapshot, including any enabled plugin hooks.
|
||||||
async fn build_hooks_for_config(
|
async fn build_hooks_for_config(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use codex_core::config::Config;
|
use codex_core::config::Config;
|
||||||
|
use codex_extension_api::ConfigContributor;
|
||||||
use codex_extension_api::ContextContributor;
|
use codex_extension_api::ContextContributor;
|
||||||
use codex_extension_api::ExtensionData;
|
use codex_extension_api::ExtensionData;
|
||||||
use codex_extension_api::ExtensionRegistryBuilder;
|
use codex_extension_api::ExtensionRegistryBuilder;
|
||||||
@@ -25,6 +26,15 @@ pub(crate) struct MemoriesExtensionConfig {
|
|||||||
pub(crate) codex_home: AbsolutePathBuf,
|
pub(crate) codex_home: AbsolutePathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MemoriesExtensionConfig {
|
||||||
|
fn from_config(config: &Config) -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: config.features.enabled(Feature::MemoryTool) && config.memories.use_memories,
|
||||||
|
codex_home: config.codex_home.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ContextContributor for MemoriesExtension {
|
impl ContextContributor for MemoriesExtension {
|
||||||
fn contribute<'a>(
|
fn contribute<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
@@ -50,11 +60,21 @@ impl ContextContributor for MemoriesExtension {
|
|||||||
|
|
||||||
impl ThreadLifecycleContributor<Config> for MemoriesExtension {
|
impl ThreadLifecycleContributor<Config> for MemoriesExtension {
|
||||||
fn on_thread_start(&self, input: ThreadStartInput<'_, Config>) {
|
fn on_thread_start(&self, input: ThreadStartInput<'_, Config>) {
|
||||||
input.thread_store.insert(MemoriesExtensionConfig {
|
input
|
||||||
enabled: input.config.features.enabled(Feature::MemoryTool)
|
.thread_store
|
||||||
&& input.config.memories.use_memories,
|
.insert(MemoriesExtensionConfig::from_config(input.config));
|
||||||
codex_home: input.config.codex_home.clone(),
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
impl ConfigContributor<Config> for MemoriesExtension {
|
||||||
|
fn on_config_changed(
|
||||||
|
&self,
|
||||||
|
_session_store: &ExtensionData,
|
||||||
|
thread_store: &ExtensionData,
|
||||||
|
_previous_config: &Config,
|
||||||
|
new_config: &Config,
|
||||||
|
) {
|
||||||
|
thread_store.insert(MemoriesExtensionConfig::from_config(new_config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +99,8 @@ impl ToolContributor for MemoriesExtension {
|
|||||||
pub fn install(registry: &mut ExtensionRegistryBuilder<Config>) {
|
pub fn install(registry: &mut ExtensionRegistryBuilder<Config>) {
|
||||||
let extension = Arc::new(MemoriesExtension);
|
let extension = Arc::new(MemoriesExtension);
|
||||||
registry.thread_lifecycle_contributor(extension.clone());
|
registry.thread_lifecycle_contributor(extension.clone());
|
||||||
registry.prompt_contributor(extension.clone());
|
registry.config_contributor(extension.clone());
|
||||||
registry.tool_contributor(extension);
|
registry.prompt_contributor(extension);
|
||||||
|
// Keep the read/retrieval tools out of app-server until that rollout is intentional.
|
||||||
|
// registry.tool_contributor(extension);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user