From 63002bdb26c939925f3fa59b9575cc0a3564cb45 Mon Sep 17 00:00:00 2001 From: "Adam Perry @ OpenAI" Date: Mon, 10 Aug 2026 19:21:33 +0000 Subject: [PATCH] Extract persisted history types into a dedicated crate (#37871) ## What changed - Add `codex-history` for model-history and persisted-rollout domain types, including `RolloutItem`, `RolloutLine`, `CompactedItem`, and initial/resumed history state. - Re-export the persisted types from `codex-rollout` and update consumers to use the new crate boundary instead of `codex-protocol`. - Preserve existing rollout serialization, including legacy numeric compacted-window IDs. ## Testing - Add `codex-history` tests for rollout JSON round trips, compacted-history compatibility, persisted history modes, and multi-agent version selection. GitOrigin-RevId: 944daa9297ddd231d3aebbdcb05fff4adf8b4e1b --- codex-rs/Cargo.lock | 22 ++ codex-rs/Cargo.toml | 2 + codex-rs/app-server-protocol/Cargo.toml | 2 + .../app-server-exports-stable.json.zst | Bin 131442 -> 131364 bytes codex-rs/app-server-protocol/src/export.rs | 2 +- .../src/protocol/thread_history.rs | 6 +- .../src/protocol/thread_history_projection.rs | 4 +- .../thread_history_projection_tests.rs | 6 +- .../app-server/src/bespoke_event_handling.rs | 2 +- .../session_importer.rs | 2 +- codex-rs/app-server/src/request_processors.rs | 6 +- .../request_processors/feedback_processor.rs | 2 +- .../thread_processor_tests.rs | 14 +- .../request_processors/token_usage_replay.rs | 2 +- codex-rs/app-server/src/thread_state.rs | 2 +- .../tests/suite/v2/git_attribution.rs | 4 +- .../app-server/tests/suite/v2/thread_fork.rs | 4 +- .../tests/suite/v2/thread_inject_items.rs | 4 +- .../app-server/tests/suite/v2/thread_list.rs | 4 +- .../app-server/tests/suite/v2/thread_read.rs | 2 +- .../tests/suite/v2/thread_resume.rs | 4 +- codex-rs/cli/Cargo.toml | 1 + codex-rs/cli/src/doctor/thread_inventory.rs | 4 +- codex-rs/core-api/Cargo.toml | 1 + codex-rs/core-api/src/lib.rs | 2 +- codex-rs/core/Cargo.toml | 1 + codex-rs/core/src/agent/control.rs | 6 +- codex-rs/core/src/agent/control_tests.rs | 6 +- codex-rs/core/src/codex_delegate.rs | 2 +- codex-rs/core/src/codex_thread.rs | 2 +- codex-rs/core/src/guardian/review_session.rs | 4 +- codex-rs/core/src/guardian/tests.rs | 2 +- codex-rs/core/src/session/handlers.rs | 2 +- codex-rs/core/src/session/mod.rs | 6 +- .../session/rollout_reconstruction_tests.rs | 6 +- codex-rs/core/src/session/tests.rs | 8 +- codex-rs/core/src/thread_manager.rs | 6 +- codex-rs/core/src/thread_manager_tests.rs | 4 +- .../core/src/thread_rollout_truncation.rs | 4 +- .../src/tools/handlers/multi_agents_tests.rs | 4 +- codex-rs/core/tests/suite/agents_md.rs | 4 +- codex-rs/core/tests/suite/client.rs | 4 +- codex-rs/core/tests/suite/compact.rs | 4 +- codex-rs/core/tests/suite/compact_remote.rs | 6 +- .../core/tests/suite/compact_remote_parity.rs | 4 +- codex-rs/core/tests/suite/fork_thread.rs | 8 +- codex-rs/core/tests/suite/guardian_review.rs | 4 +- codex-rs/core/tests/suite/hooks.rs | 4 +- codex-rs/core/tests/suite/image_rollout.rs | 4 +- codex-rs/core/tests/suite/items.rs | 4 +- .../core/tests/suite/mcp_tool_exposure.rs | 4 +- .../core/tests/suite/mcp_turn_metadata.rs | 4 +- codex-rs/core/tests/suite/model_switching.rs | 4 +- codex-rs/core/tests/suite/pending_input.rs | 4 +- .../core/tests/suite/realtime_conversation.rs | 4 +- codex-rs/core/tests/suite/remote_env.rs | 4 +- codex-rs/core/tests/suite/resume_warning.rs | 6 +- codex-rs/core/tests/suite/review.rs | 4 +- codex-rs/core/tests/suite/rmcp_client.rs | 2 +- .../tests/suite/spawn_agent_description.rs | 4 +- codex-rs/core/tests/suite/sqlite_state.rs | 4 +- .../tests/suite/subagent_notifications.rs | 2 +- .../tests/suite/unstable_features_warning.rs | 2 +- .../tests/suite/user_message_admission.rs | 4 +- codex-rs/exec/Cargo.toml | 1 + codex-rs/exec/src/lib.rs | 4 +- codex-rs/ext/goal/Cargo.toml | 1 + codex-rs/ext/goal/src/api.rs | 2 +- .../src/sessions/append.rs | 2 +- .../src/sessions/export.rs | 2 +- .../src/sessions/mod.rs | 2 +- codex-rs/history/BUILD.bazel | 6 + codex-rs/history/Cargo.toml | 23 ++ codex-rs/history/src/lib.rs | 344 ++++++++++++++++ codex-rs/history/src/tests.rs | 179 +++++++++ codex-rs/memories/write/src/phase1.rs | 2 +- codex-rs/memories/write/src/startup_tests.rs | 4 +- codex-rs/protocol/src/compacted_item.rs | 106 ----- codex-rs/protocol/src/lib.rs | 1 - codex-rs/protocol/src/protocol.rs | 366 ------------------ codex-rs/rollout/Cargo.toml | 1 + codex-rs/rollout/src/compression_tests.rs | 6 +- codex-rs/rollout/src/lib.rs | 5 + codex-rs/rollout/src/list.rs | 4 +- codex-rs/rollout/src/metadata.rs | 2 +- codex-rs/rollout/src/metadata_tests.rs | 6 +- codex-rs/rollout/src/model_context.rs | 2 +- codex-rs/rollout/src/ordinal.rs | 4 +- codex-rs/rollout/src/persistence_metrics.rs | 2 +- .../rollout/src/persistence_metrics_tests.rs | 2 +- codex-rs/rollout/src/policy.rs | 2 +- codex-rs/rollout/src/recorder.rs | 8 +- codex-rs/rollout/src/recorder_tests.rs | 4 +- codex-rs/rollout/src/search.rs | 4 +- codex-rs/rollout/src/session_index_tests.rs | 4 +- codex-rs/rollout/src/state_db.rs | 2 +- codex-rs/rollout/src/state_db_tests.rs | 2 +- codex-rs/rollout/src/tests.rs | 4 +- codex-rs/state/Cargo.toml | 1 + codex-rs/state/src/extract.rs | 4 +- codex-rs/state/src/runtime.rs | 2 +- codex-rs/thread-store/src/in_memory.rs | 2 +- codex-rs/thread-store/src/live_thread.rs | 2 +- .../thread-store/src/local/live_writer.rs | 2 +- codex-rs/thread-store/src/local/mod.rs | 2 +- .../thread-store/src/local/model_context.rs | 4 +- .../src/local/model_context_tests.rs | 6 +- .../thread-store/src/local/read_thread.rs | 4 +- .../src/local/rollout_lineage_tests.rs | 4 +- .../src/local/rollout_migration.rs | 4 +- .../local/rollout_migration/canonicalizer.rs | 4 +- .../local/rollout_migration/line_parser.rs | 2 +- .../rollout_migration/line_parser_tests.rs | 2 +- .../src/local/rollout_migration/publish.rs | 4 +- .../local/rollout_migration/rollback_plan.rs | 6 +- .../rollout_migration/rollback_replay.rs | 2 +- .../local/rollout_migration/startup_tests.rs | 4 +- .../src/local/rollout_migration/subagent.rs | 2 +- .../src/local/rollout_migration_tests.rs | 6 +- .../src/local/thread_history/read_tests.rs | 4 +- .../local/thread_history_materialization.rs | 2 +- .../thread_history_materialization_tests.rs | 4 +- .../src/local/update_thread_metadata.rs | 2 +- .../thread-store/src/thread_metadata_sync.rs | 4 +- codex-rs/thread-store/src/types.rs | 2 +- codex-rs/tui/Cargo.toml | 1 + codex-rs/tui/src/app/tests.rs | 2 +- 127 files changed, 791 insertions(+), 673 deletions(-) create mode 100644 codex-rs/history/BUILD.bazel create mode 100644 codex-rs/history/Cargo.toml create mode 100644 codex-rs/history/src/lib.rs create mode 100644 codex-rs/history/src/tests.rs delete mode 100644 codex-rs/protocol/src/compacted_item.rs diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 0255bcf0bb..4d67f63830 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -2142,7 +2142,9 @@ dependencies = [ "codex-app-server-protocol-noop-macros", "codex-experimental-api-macros", "codex-extension-items", + "codex-history", "codex-protocol", + "codex-rollout", "codex-secrets", "codex-shell-command", "codex-utils-absolute-path", @@ -2387,6 +2389,7 @@ dependencies = [ "codex-features", "codex-git-attribution", "codex-git-utils", + "codex-history", "codex-home", "codex-http-client", "codex-install-context", @@ -2745,6 +2748,7 @@ dependencies = [ "codex-feedback", "codex-file-system", "codex-git-utils", + "codex-history", "codex-home", "codex-hooks", "codex-http-client", @@ -2852,6 +2856,7 @@ dependencies = [ "codex-exec-server", "codex-extension-api", "codex-features", + "codex-history", "codex-home", "codex-image-generation-extension", "codex-login", @@ -2939,6 +2944,7 @@ dependencies = [ "codex-core", "codex-feedback", "codex-git-utils", + "codex-history", "codex-login", "codex-model-provider-info", "codex-otel", @@ -3251,6 +3257,7 @@ dependencies = [ "codex-extension-api", "codex-otel", "codex-protocol", + "codex-rollout", "codex-state", "codex-tools", "codex-utils-absolute-path", @@ -3272,6 +3279,18 @@ dependencies = [ "codex-protocol", ] +[[package]] +name = "codex-history" +version = "0.0.0" +dependencies = [ + "anyhow", + "codex-protocol", + "pretty_assertions", + "schemars 0.8.22", + "serde", + "serde_json", +] + [[package]] name = "codex-home" version = "0.0.0" @@ -3977,6 +3996,7 @@ dependencies = [ "codex-extension-items", "codex-file-search", "codex-git-utils", + "codex-history", "codex-otel", "codex-protocol", "codex-state", @@ -4155,6 +4175,7 @@ dependencies = [ "anyhow", "chrono", "codex-git-utils", + "codex-history", "codex-protocol", "codex-utils-absolute-path", "libsqlite3-sys", @@ -4290,6 +4311,7 @@ dependencies = [ "codex-feedback", "codex-file-search", "codex-git-utils", + "codex-history", "codex-http-client", "codex-install-context", "codex-login", diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index e776322fa1..f2b7192e77 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -43,6 +43,7 @@ members = [ "core-plugins", "diagnostics", "hooks", + "history", "http-client", "secrets", "exec", @@ -206,6 +207,7 @@ codex-file-search = { path = "file-search" } codex-file-watcher = { path = "file-watcher" } codex-git-utils = { path = "git-utils" } codex-hooks = { path = "hooks" } +codex-history = { path = "history" } codex-keyring-store = { path = "keyring-store" } codex-linux-sandbox = { path = "linux-sandbox" } codex-lmstudio = { path = "lmstudio" } diff --git a/codex-rs/app-server-protocol/Cargo.toml b/codex-rs/app-server-protocol/Cargo.toml index e33d4ed660..781aafa8d8 100644 --- a/codex-rs/app-server-protocol/Cargo.toml +++ b/codex-rs/app-server-protocol/Cargo.toml @@ -17,7 +17,9 @@ anyhow = { workspace = true } codex-experimental-api-macros = { workspace = true } codex-app-server-protocol-noop-macros = { workspace = true } codex-extension-items = { workspace = true } +codex-history = { workspace = true } codex-protocol = { workspace = true } +codex-rollout = { workspace = true } codex-secrets = { workspace = true } codex-shell-command = { workspace = true } codex-utils-absolute-path = { workspace = true } diff --git a/codex-rs/app-server-protocol/schema/precomputed/app-server-exports-stable.json.zst b/codex-rs/app-server-protocol/schema/precomputed/app-server-exports-stable.json.zst index e664e871fdc7989fd94f174a14517591815deb77..63d5c3269d1a838342a6c681fc099e598c02eea7 100644 GIT binary patch delta 16356 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 z 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 delta 16429 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 Option Result<()> { - use codex_protocol::protocol::RolloutItem; - use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMetaLine; + use codex_rollout::RolloutItem; + use codex_rollout::RolloutLine; use std::fs; use std::fs::FileTimes; @@ -1187,9 +1187,9 @@ mod thread_processor_behavior_tests { #[tokio::test] async fn read_summary_from_rollout_preserves_agent_nickname() -> Result<()> { - use codex_protocol::protocol::RolloutItem; - use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMetaLine; + use codex_rollout::RolloutItem; + use codex_rollout::RolloutLine; use std::fs; let temp_dir = TempDir::new()?; @@ -1239,9 +1239,9 @@ mod thread_processor_behavior_tests { #[tokio::test] async fn read_summary_from_rollout_preserves_forked_from_id() -> Result<()> { - use codex_protocol::protocol::RolloutItem; - use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMetaLine; + use codex_rollout::RolloutItem; + use codex_rollout::RolloutLine; use std::fs; let temp_dir = TempDir::new()?; diff --git a/codex-rs/app-server/src/request_processors/token_usage_replay.rs b/codex-rs/app-server/src/request_processors/token_usage_replay.rs index 50a59aa659..13d7ca2609 100644 --- a/codex-rs/app-server/src/request_processors/token_usage_replay.rs +++ b/codex-rs/app-server/src/request_processors/token_usage_replay.rs @@ -20,7 +20,7 @@ use codex_app_server_protocol::TurnStatus; use codex_core::CodexThread; use codex_protocol::ThreadId; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; +use codex_rollout::RolloutItem; use crate::outgoing_message::ConnectionId; use crate::outgoing_message::OutgoingMessageSender; diff --git a/codex-rs/app-server/src/thread_state.rs b/codex-rs/app-server/src/thread_state.rs index 72dc7e15b9..3cd45f29ce 100644 --- a/codex-rs/app-server/src/thread_state.rs +++ b/codex-rs/app-server/src/thread_state.rs @@ -17,7 +17,7 @@ use codex_protocol::items::AgentMessageContent as CoreAgentMessageContent; use codex_protocol::items::TurnItem as CoreTurnItem; use codex_protocol::models::MessagePhase; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; +use codex_rollout::RolloutItem; use codex_rollout::state_db::StateDbHandle; use codex_utils_path_uri::LegacyAppPathString; use std::collections::HashMap; diff --git a/codex-rs/app-server/tests/suite/v2/git_attribution.rs b/codex-rs/app-server/tests/suite/v2/git_attribution.rs index dcfdd97163..fcd0f53d59 100644 --- a/codex-rs/app-server/tests/suite/v2/git_attribution.rs +++ b/codex-rs/app-server/tests/suite/v2/git_attribution.rs @@ -25,8 +25,8 @@ use codex_app_server_protocol::UserInput; use codex_config::types::AuthCredentialsStoreMode; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use core_test_support::responses; use core_test_support::skip_if_no_network; use pretty_assertions::assert_eq; diff --git a/codex-rs/app-server/tests/suite/v2/thread_fork.rs b/codex-rs/app-server/tests/suite/v2/thread_fork.rs index defe31c833..5491a4aa7a 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_fork.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_fork.rs @@ -54,11 +54,11 @@ use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::MultiAgentVersion; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use codex_rollout::append_rollout_item_to_path; use codex_rollout::append_thread_name; use codex_rollout::read_session_meta_line; diff --git a/codex-rs/app-server/tests/suite/v2/thread_inject_items.rs b/codex-rs/app-server/tests/suite/v2/thread_inject_items.rs index 13ed15ed19..89afc6e537 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_inject_items.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_inject_items.rs @@ -12,8 +12,8 @@ use codex_app_server_protocol::UserInput as V2UserInput; use codex_core::RolloutRecorder; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; -use codex_protocol::protocol::InitialHistory; -use codex_protocol::protocol::RolloutItem; +use codex_rollout::InitialHistory; +use codex_rollout::RolloutItem; use core_test_support::responses; use core_test_support::responses::strip_response_item_id; use core_test_support::responses::strip_response_item_ids_from_json; diff --git a/codex-rs/app-server/tests/suite/v2/thread_list.rs b/codex-rs/app-server/tests/suite/v2/thread_list.rs index ac91f1e117..2a56210dc9 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_list.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_list.rs @@ -39,10 +39,10 @@ use codex_git_utils::GitSha; use codex_protocol::ThreadId; use codex_protocol::protocol::GitInfo as CoreGitInfo; use codex_protocol::protocol::MultiAgentVersion; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource as CoreSessionSource; use codex_protocol::protocol::SubAgentSource; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use codex_rollout::append_rollout_item_to_path; use codex_rollout::read_session_meta_line; use codex_state::DirectionalThreadSpawnEdgeStatus; diff --git a/codex-rs/app-server/tests/suite/v2/thread_read.rs b/codex-rs/app-server/tests/suite/v2/thread_read.rs index 226643eeea..0c888581f0 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_read.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_read.rs @@ -63,7 +63,6 @@ use codex_protocol::models::MessagePhase; use codex_protocol::protocol::AgentMessageEvent; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource as ProtocolSessionSource; use codex_protocol::protocol::ThreadMemoryMode; use codex_protocol::protocol::TurnCompleteEvent; @@ -71,6 +70,7 @@ use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; use codex_protocol::user_input::ByteRange; use codex_protocol::user_input::TextElement; +use codex_rollout::RolloutItem; use codex_thread_store::AppendThreadItemsParams; use codex_thread_store::CreateThreadParams; use codex_thread_store::InMemoryThreadStore; diff --git a/codex-rs/app-server/tests/suite/v2/thread_resume.rs b/codex-rs/app-server/tests/suite/v2/thread_resume.rs index e6a410fde0..cfc9e53bef 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_resume.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_resume.rs @@ -79,13 +79,11 @@ use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::protocol::AgentMessageEvent; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ImageGenerationEndEvent; use codex_protocol::protocol::McpInvocation; use codex_protocol::protocol::McpToolCallEndEvent; use codex_protocol::protocol::MultiAgentVersion; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource as RolloutSessionSource; @@ -97,6 +95,8 @@ use codex_protocol::protocol::TurnAbortedEvent; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::user_input::ByteRange; use codex_protocol::user_input::TextElement; +use codex_rollout::CompactedItem; +use codex_rollout::RolloutItem; use codex_rollout::append_rollout_item_to_path; use codex_rollout::read_session_meta_line; use codex_state::StateRuntime; diff --git a/codex-rs/cli/Cargo.toml b/codex-rs/cli/Cargo.toml index 0fe910d272..30e5a52a02 100644 --- a/codex-rs/cli/Cargo.toml +++ b/codex-rs/cli/Cargo.toml @@ -40,6 +40,7 @@ codex-utils-cli = { workspace = true } codex-config = { workspace = true } codex-core = { workspace = true } codex-core-plugins = { workspace = true } +codex-history = { workspace = true } codex-home = { workspace = true } codex-http-client = { workspace = true } codex-exec = { workspace = true } diff --git a/codex-rs/cli/src/doctor/thread_inventory.rs b/codex-rs/cli/src/doctor/thread_inventory.rs index 8b220c9c68..1ac5e89b5f 100644 --- a/codex-rs/cli/src/doctor/thread_inventory.rs +++ b/codex-rs/cli/src/doctor/thread_inventory.rs @@ -4,9 +4,9 @@ use super::CheckStatus; use super::Config; use super::DoctorCheck; use super::DoctorIssue; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::protocol::InternalSessionSource; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_state::ThreadStateAuditRow; diff --git a/codex-rs/core-api/Cargo.toml b/codex-rs/core-api/Cargo.toml index a6f061eadf..b82d5ee480 100644 --- a/codex-rs/core-api/Cargo.toml +++ b/codex-rs/core-api/Cargo.toml @@ -21,6 +21,7 @@ codex-config = { workspace = true } codex-core = { workspace = true } codex-extension-api = { workspace = true } codex-home = { workspace = true } +codex-history = { workspace = true } codex-image-generation-extension = { workspace = true } codex-exec-server = { workspace = true } codex-features = { workspace = true } diff --git a/codex-rs/core-api/src/lib.rs b/codex-rs/core-api/src/lib.rs index bc22a12c40..2bcb53d4ae 100644 --- a/codex-rs/core-api/src/lib.rs +++ b/codex-rs/core-api/src/lib.rs @@ -73,6 +73,7 @@ pub use codex_extension_api::UserInstructionsProvider; pub use codex_extension_api::empty_extension_registry; pub use codex_features::Feature; pub use codex_features::Features; +pub use codex_history::InitialHistory; pub use codex_home::CodexHomeUserInstructionsProvider; pub use codex_image_generation_extension::install as install_image_generation_extension; pub use codex_login::AuthHeaders; @@ -103,7 +104,6 @@ pub use codex_protocol::models::PermissionProfile; pub use codex_protocol::openai_models::ModelPreset; pub use codex_protocol::protocol::AskForApproval; pub use codex_protocol::protocol::EventMsg; -pub use codex_protocol::protocol::InitialHistory; pub use codex_protocol::protocol::Op; pub use codex_protocol::protocol::SessionConfiguredEvent; pub use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/core/Cargo.toml b/codex-rs/core/Cargo.toml index 7e6e4576d0..78e6905ded 100644 --- a/codex-rs/core/Cargo.toml +++ b/codex-rs/core/Cargo.toml @@ -49,6 +49,7 @@ codex-models-manager = { workspace = true } codex-shell-command = { workspace = true } codex-execpolicy = { workspace = true } codex-git-utils = { workspace = true } +codex-history = { workspace = true } codex-hooks = { workspace = true } codex-http-client = { workspace = true } codex-install-context = { workspace = true } diff --git a/codex-rs/core/src/agent/control.rs b/codex-rs/core/src/agent/control.rs index 1ba0317294..36690f937b 100644 --- a/codex-rs/core/src/agent/control.rs +++ b/codex-rs/core/src/agent/control.rs @@ -20,6 +20,9 @@ use crate::thread_manager::ThreadIdGenerator; use crate::thread_manager::ThreadManagerState; use crate::thread_manager::default_thread_id_generator; use crate::thread_rollout_truncation::truncate_rollout_to_last_n_fork_turns; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; +use codex_history::RolloutItem; use codex_protocol::AgentPath; use codex_protocol::SessionId; use codex_protocol::ThreadId; @@ -30,12 +33,9 @@ use codex_protocol::models::ContentItem; use codex_protocol::models::MessagePhase; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::MultiAgentVersion; use codex_protocol::protocol::Op; -use codex_protocol::protocol::ResumedHistory; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::ThreadHistoryMode; diff --git a/codex-rs/core/src/agent/control_tests.rs b/codex-rs/core/src/agent/control_tests.rs index db48f9bdce..c03e3a63cb 100644 --- a/codex-rs/core/src/agent/control_tests.rs +++ b/codex-rs/core/src/agent/control_tests.rs @@ -16,6 +16,9 @@ use assert_matches::assert_matches; use codex_extension_api::ExtensionDataInit; use codex_extension_api::empty_extension_registry; use codex_features::Feature; +use codex_history::CompactedItem; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_protocol::AgentPath; @@ -34,13 +37,10 @@ use codex_protocol::models::MessagePhase; use codex_protocol::models::PermissionProfile; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AskForApproval; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::ErrorEvent; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::ItemCompletedEvent; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::ThreadHistoryMode; diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index 0f5061d5c4..6fb3c56c4b 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -58,10 +58,10 @@ use crate::session::SessionSpawnArgs; use crate::session::emit_subagent_session_started; use crate::session::session::Session; use crate::session::turn_context::TurnContext; +use codex_history::InitialHistory; use codex_login::AuthManager; use codex_models_manager::manager::SharedModelsManager; use codex_protocol::error::CodexErr; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::MultiAgentVersion; #[cfg(test)] diff --git a/codex-rs/core/src/codex_thread.rs b/codex-rs/core/src/codex_thread.rs index ba0bfcb741..469afeed0f 100644 --- a/codex-rs/core/src/codex_thread.rs +++ b/codex-rs/core/src/codex_thread.rs @@ -14,6 +14,7 @@ use codex_diagnostics::GaugeGuard; use codex_exec_server::SelectedCapabilityRootsStatus; use codex_extension_api::ThreadIdleCause; use codex_features::Feature; +use codex_history::RolloutItem; use codex_otel::SessionTelemetry; use codex_protocol::ThreadId; use codex_protocol::config_types::ApprovalsReviewer; @@ -34,7 +35,6 @@ use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::Event; use codex_protocol::protocol::MultiAgentVersion; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionConfiguredEvent; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index 2b3814fde0..7c6bff792d 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -9,6 +9,8 @@ use codex_analytics::GuardianReviewAnalyticsResult; use codex_analytics::GuardianReviewSessionAnalyticsParams; use codex_analytics::GuardianReviewSessionKind; use codex_extension_api::UserInstructions; +use codex_history::InitialHistory; +use codex_history::RolloutItem; use codex_protocol::ThreadId; use codex_protocol::config_types::AutoCompactTokenLimitScope; use codex_protocol::config_types::Personality; @@ -23,9 +25,7 @@ use codex_protocol::protocol::CodexErrorInfo; use codex_protocol::protocol::ErrorEvent; use codex_protocol::protocol::Event; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::TokenUsage; diff --git a/codex-rs/core/src/guardian/tests.rs b/codex-rs/core/src/guardian/tests.rs index e09250eb47..8aedea8fce 100644 --- a/codex-rs/core/src/guardian/tests.rs +++ b/codex-rs/core/src/guardian/tests.rs @@ -28,6 +28,7 @@ use codex_config::config_toml::ConfigToml; use codex_config::types::McpServerConfig; use codex_exec_server::LOCAL_FS; use codex_features::Feature; +use codex_history::RolloutItem; use codex_model_provider::create_model_provider; use codex_model_provider_info::AMAZON_BEDROCK_GPT_5_4_MODEL_ID; use codex_model_provider_info::AMAZON_BEDROCK_PROVIDER_ID; @@ -56,7 +57,6 @@ use codex_protocol::protocol::GuardianAssessmentStatus; use codex_protocol::protocol::GuardianRiskLevel; use codex_protocol::protocol::GuardianUserAuthorization; use codex_protocol::protocol::ReviewDecision; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::TurnCompleteEvent; use codex_utils_path_uri::PathUri; use core_test_support::PathBufExt; diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 09fedfb125..3308d2dd95 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -23,6 +23,7 @@ use crate::tasks::UserShellCommandMode; use crate::tasks::UserShellCommandTask; use crate::tasks::execute_user_shell_command; use crate::user_message_admission::UserMessageAdmission; +use codex_history::RolloutItem; use codex_protocol::error::CodexErr; use codex_protocol::error::Result as CodexResult; use codex_protocol::models::ContentItem; @@ -40,7 +41,6 @@ use codex_protocol::protocol::RealtimeConversationListVoicesResponseEvent; use codex_protocol::protocol::RealtimeVoicesList; use codex_protocol::protocol::ReviewDecision; use codex_protocol::protocol::ReviewRequest; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadMemoryMode; use codex_protocol::protocol::ThreadRolledBackEvent; use codex_protocol::protocol::ThreadSettingsAppliedEvent; diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index b2d121a39f..402179accf 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -65,6 +65,7 @@ use codex_extension_api::TurnContextContributionInput; use codex_features::FEATURES; use codex_features::Feature; use codex_features::unstable_features_warning_event; +use codex_history::RolloutItem; use codex_hooks::Hooks; use codex_hooks::HooksConfig; use codex_login::AuthManager; @@ -120,7 +121,6 @@ use codex_protocol::protocol::ItemStartedEvent; use codex_protocol::protocol::MULTI_AGENT_MODE_OPEN_TAG; use codex_protocol::protocol::MultiAgentVersion; use codex_protocol::protocol::RawResponseItemEvent; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::ThreadHistoryMode; @@ -336,6 +336,8 @@ use codex_core_plugins::PluginCommandAttribution; use codex_core_plugins::PluginsManager; use codex_core_plugins::RecommendedPluginCandidatesInput; use codex_git_utils::get_git_repo_root; +use codex_history::CompactedItem; +use codex_history::InitialHistory; use codex_mcp::McpConfig; use codex_mcp::effective_mcp_servers; use codex_otel::SessionTelemetry; @@ -354,13 +356,11 @@ use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig; use codex_protocol::protocol::ApplyPatchApprovalRequestEvent; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::CodexErrorInfo; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::DeprecationNoticeEvent; use codex_protocol::protocol::ErrorEvent; use codex_protocol::protocol::Event; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ExecApprovalRequestEvent; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::ModelRerouteEvent; use codex_protocol::protocol::ModelRerouteReason; use codex_protocol::protocol::ModelVerification; diff --git a/codex-rs/core/src/session/rollout_reconstruction_tests.rs b/codex-rs/core/src/session/rollout_reconstruction_tests.rs index 6fc6f449c9..da020ad61c 100644 --- a/codex-rs/core/src/session/rollout_reconstruction_tests.rs +++ b/codex-rs/core/src/session/rollout_reconstruction_tests.rs @@ -2,14 +2,14 @@ use super::*; use super::tests::build_world_state_from_turn_context; use super::tests::make_session_and_context; +use codex_history::CompactedItem; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; use codex_protocol::AgentPath; use codex_protocol::ThreadId; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; -use codex_protocol::protocol::CompactedItem; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InterAgentCommunication; -use codex_protocol::protocol::ResumedHistory; use codex_protocol::protocol::SessionContextWindow; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 162d3a1e00..9aade4d1b2 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -105,6 +105,10 @@ use codex_config::permissions_toml::PermissionsToml; use codex_execpolicy::Decision; use codex_execpolicy::NetworkRuleProtocol; use codex_execpolicy::Policy; +use codex_history::CompactedItem; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; +use codex_history::RolloutItem; use codex_network_proxy::NetworkProxyConfig; use codex_otel::MetricsClient; use codex_otel::MetricsConfig; @@ -120,11 +124,9 @@ use codex_protocol::models::InternalChatMessageMetadataPassthrough; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::CodexErrorInfo; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::ConversationAudioParams; use codex_protocol::protocol::CreditsSnapshot; use codex_protocol::protocol::GranularApprovalConfig; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::MultiAgentVersion; use codex_protocol::protocol::NetworkApprovalProtocol; @@ -134,8 +136,6 @@ use codex_protocol::protocol::RealtimeAudioFrame; use codex_protocol::protocol::RealtimeConversationListVoicesResponseEvent; use codex_protocol::protocol::RealtimeVoice; use codex_protocol::protocol::RealtimeVoicesList; -use codex_protocol::protocol::ResumedHistory; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::Submission; diff --git a/codex-rs/core/src/thread_manager.rs b/codex-rs/core/src/thread_manager.rs index f35d293ecc..5a53c6fe39 100644 --- a/codex-rs/core/src/thread_manager.rs +++ b/codex-rs/core/src/thread_manager.rs @@ -35,6 +35,9 @@ use codex_extension_api::LoadedUserInstructions; use codex_extension_api::UserInstructionsProvider; use codex_extension_api::empty_extension_registry; use codex_features::Feature; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; +use codex_history::RolloutItem; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_login::default_client::CODEX_INTERNAL_ORIGINATOR_OVERRIDE_ENV_VAR; @@ -53,11 +56,8 @@ use codex_protocol::mcp::OPENAI_STANDARD_FORM_INPUT_EXTENSION_ID; use codex_protocol::openai_models::ModelPreset; use codex_protocol::protocol::Event; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::MultiAgentVersion; use codex_protocol::protocol::Op; -use codex_protocol::protocol::ResumedHistory; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionConfiguredEvent; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; diff --git a/codex-rs/core/src/thread_manager_tests.rs b/codex-rs/core/src/thread_manager_tests.rs index 876a83d1c0..afcef58be9 100644 --- a/codex-rs/core/src/thread_manager_tests.rs +++ b/codex-rs/core/src/thread_manager_tests.rs @@ -11,6 +11,8 @@ use crate::session::tests::make_session_and_context; use crate::tasks::InterruptedTurnHistoryMarker; use crate::tasks::interrupted_turn_history_marker; use codex_extension_api::empty_extension_registry; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; use codex_models_manager::manager::RefreshStrategy; use codex_protocol::ResponseItemId; use codex_protocol::capabilities::CapabilityRootLocation; @@ -23,9 +25,7 @@ use codex_protocol::models::ReasoningItemReasoningSummary; use codex_protocol::models::ResponseItem; use codex_protocol::openai_models::ModelsResponse; use codex_protocol::protocol::AgentMessageEvent; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InternalSessionSource; -use codex_protocol::protocol::ResumedHistory; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/core/src/thread_rollout_truncation.rs b/codex-rs/core/src/thread_rollout_truncation.rs index 795958f83c..93b1727583 100644 --- a/codex-rs/core/src/thread_rollout_truncation.rs +++ b/codex-rs/core/src/thread_rollout_truncation.rs @@ -7,14 +7,14 @@ use crate::context_manager::is_user_turn_boundary; use crate::event_mapping; use codex_app_server_protocol::TurnStatus; use codex_app_server_protocol::build_turns_from_rollout_items; +use codex_history::InitialHistory; +use codex_history::RolloutItem; use codex_protocol::error::CodexErr; use codex_protocol::error::Result as CodexResult; use codex_protocol::items::TurnItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InterAgentCommunication; -use codex_protocol::protocol::RolloutItem; pub(crate) fn initial_history_has_prior_user_turns(conversation_history: &InitialHistory) -> bool { conversation_history.scan_rollout_items(rollout_item_is_user_turn_boundary) diff --git a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs index 6e18dfe971..7a42cd4f3a 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -23,6 +23,8 @@ use crate::tools::handlers::multi_agents_v2::WaitAgentHandler as WaitAgentHandle use crate::turn_diff_tracker::TurnDiffTracker; use codex_extension_api::empty_extension_registry; use codex_features::Feature; +use codex_history::InitialHistory; +use codex_history::RolloutItem; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_model_provider::create_model_provider; @@ -49,11 +51,9 @@ use codex_protocol::protocol::FileSystemAccessMode; use codex_protocol::protocol::FileSystemPath; use codex_protocol::protocol::FileSystemSandboxEntry; use codex_protocol::protocol::FileSystemSandboxPolicy; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::NetworkSandboxPolicy; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; diff --git a/codex-rs/core/tests/suite/agents_md.rs b/codex-rs/core/tests/suite/agents_md.rs index 62b78a249b..5e647c0e34 100644 --- a/codex-rs/core/tests/suite/agents_md.rs +++ b/codex-rs/core/tests/suite/agents_md.rs @@ -6,11 +6,11 @@ use codex_exec_server::CreateDirectoryOptions; use codex_exec_server::LOCAL_ENVIRONMENT_ID; use codex_exec_server::REMOTE_ENVIRONMENT_ID; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_home::CodexHomeUserInstructionsProvider; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::TurnEnvironmentSelection; use codex_protocol::user_input::UserInput; use codex_utils_absolute_path::AbsolutePathBuf; diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 75f14e1895..9cea9b884c 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -10,6 +10,8 @@ use codex_core::resolve_installation_id; use codex_core::thread_store_from_config; use codex_extension_api::empty_extension_registry; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::AuthKeyringBackendKind; use codex_login::AuthManager; use codex_login::CodexAuth; @@ -48,8 +50,6 @@ use codex_protocol::openai_models::InputModality; use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index dc425387c7..12087f84f7 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -4,6 +4,8 @@ use codex_core::compact::SUMMARIZATION_PROMPT; use codex_core::compact::SUMMARY_PREFIX; use codex_core::config::Config; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_model_provider_info::ModelProviderInfo; use codex_model_provider_info::built_in_model_providers; @@ -20,8 +22,6 @@ use codex_protocol::protocol::HookRunStatus; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::ItemStartedEvent; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::WarningEvent; use codex_protocol::user_input::UserInput; use codex_utils_absolute_path::AbsolutePathBuf; diff --git a/codex-rs/core/tests/suite/compact_remote.rs b/codex-rs/core/tests/suite/compact_remote.rs index 8a86ef74a2..4384e8da4b 100644 --- a/codex-rs/core/tests/suite/compact_remote.rs +++ b/codex-rs/core/tests/suite/compact_remote.rs @@ -8,6 +8,9 @@ use codex_core::StartThreadOptions; use codex_core::X_CODEX_ROUTING_HINT_HEADER; use codex_core::compact::SUMMARY_PREFIX; use codex_features::Feature; +use codex_history::InitialHistory; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_login::auth::AgentIdentityAuth; use codex_login::auth::AgentIdentityAuthRecord; @@ -33,7 +36,6 @@ use codex_protocol::models::ResponseItem; use codex_protocol::openai_models::InputModality; use codex_protocol::protocol::ConversationStartParams; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::ItemStartedEvent; @@ -41,8 +43,6 @@ use codex_protocol::protocol::Op; use codex_protocol::protocol::RealtimeConversationRealtimeEvent; use codex_protocol::protocol::RealtimeEvent; use codex_protocol::protocol::RealtimeOutputModality; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::user_input::UserInput; use core_test_support::PathBufExt; use core_test_support::apps_test_server::configure_search_capable_model; diff --git a/codex-rs/core/tests/suite/compact_remote_parity.rs b/codex-rs/core/tests/suite/compact_remote_parity.rs index fd06a0b433..ffc9762e57 100644 --- a/codex-rs/core/tests/suite/compact_remote_parity.rs +++ b/codex-rs/core/tests/suite/compact_remote_parity.rs @@ -4,12 +4,12 @@ use std::path::PathBuf; use anyhow::Result; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_protocol::config_types::ServiceTier; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::user_input::UserInput; use core_test_support::hooks::trust_discovered_hooks; use core_test_support::responses; diff --git a/codex-rs/core/tests/suite/fork_thread.rs b/codex-rs/core/tests/suite/fork_thread.rs index 140af23c3f..c93d03e40b 100644 --- a/codex-rs/core/tests/suite/fork_thread.rs +++ b/codex-rs/core/tests/suite/fork_thread.rs @@ -4,14 +4,14 @@ use codex_core::ForkSnapshot; use codex_core::NewThread; use codex_core::ThreadConfigSnapshot; use codex_core::parse_turn_item; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::items::TurnItem; use codex_protocol::mcp::ClientMcpExtensions; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::Op; -use codex_protocol::protocol::ResumedHistory; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadSettingsAppliedEvent; use codex_protocol::user_input::UserInput; diff --git a/codex-rs/core/tests/suite/guardian_review.rs b/codex-rs/core/tests/suite/guardian_review.rs index af465ec376..4f83ced602 100644 --- a/codex-rs/core/tests/suite/guardian_review.rs +++ b/codex-rs/core/tests/suite/guardian_review.rs @@ -13,6 +13,8 @@ use codex_core::config::CurrentTimeReminderConfig; use codex_core::sandboxing::SandboxPermissions; use codex_features::CurrentTimeSource; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_protocol::ThreadId; use codex_protocol::config_types::ApprovalsReviewer; @@ -21,8 +23,6 @@ use codex_protocol::openai_models::ModelsResponse; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::TurnAbortReason; use codex_protocol::user_input::UserInput; diff --git a/codex-rs/core/tests/suite/hooks.rs b/codex-rs/core/tests/suite/hooks.rs index 5fe2cc882a..f12e9f38ed 100644 --- a/codex-rs/core/tests/suite/hooks.rs +++ b/codex-rs/core/tests/suite/hooks.rs @@ -8,6 +8,8 @@ use codex_core::config::Config; use codex_core::config::Constrained; use codex_core::config::ThreadStoreConfig; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_model_provider_info::ModelProviderInfo; use codex_model_provider_info::built_in_model_providers; use codex_plugin::PluginHookSource; @@ -21,8 +23,6 @@ use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::request_permissions::PermissionGrantScope; diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index 1f937fbdd7..6cdb1fac8e 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -2,6 +2,8 @@ use anyhow::Context; use base64::Engine; use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::models::ContentItem; use codex_protocol::models::DEFAULT_IMAGE_DETAIL; use codex_protocol::models::ImageDetail; @@ -10,8 +12,6 @@ use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::user_input::UserInput; use codex_utils_image::data_url_from_bytes; use core_test_support::TempDirExt; diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index a0e9ca64fb..6bde20cc9f 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -2,6 +2,8 @@ use anyhow::Ok; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::config_types::CollaborationMode; use codex_protocol::config_types::ModeKind; use codex_protocol::config_types::Settings; @@ -14,8 +16,6 @@ use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::ItemStartedEvent; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::user_input::ByteRange; use codex_protocol::user_input::TextElement; diff --git a/codex-rs/core/tests/suite/mcp_tool_exposure.rs b/codex-rs/core/tests/suite/mcp_tool_exposure.rs index 4235a39aa4..d3dfe3e0d7 100644 --- a/codex-rs/core/tests/suite/mcp_tool_exposure.rs +++ b/codex-rs/core/tests/suite/mcp_tool_exposure.rs @@ -9,14 +9,14 @@ use codex_extension_api::McpServerContributor; use codex_extension_api::ThreadLifecycleContributor; use codex_extension_api::ThreadStartInput; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_mcp::CODEX_APPS_MCP_SERVER_NAME; use codex_mcp::McpResourceClient; use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::request_user_input::RequestUserInputAnswer; diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index 713113f2cf..d6c6474487 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -6,6 +6,8 @@ use codex_config::test_support::CloudConfigBundleFixture; use codex_config::types::AppToolApproval; use codex_core::config::Config; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::CollaborationMode; use codex_protocol::config_types::ModeKind; @@ -17,8 +19,6 @@ use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::ElicitationAction; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::request_user_input::RequestUserInputAnswer; use codex_protocol::request_user_input::RequestUserInputResponse; use codex_protocol::user_input::UserInput; diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index 941a2a04b2..bd4df3f6d3 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -3,6 +3,8 @@ use codex_config::types::Personality; use codex_core::CodexThread; use codex_core::ForkSnapshot; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_models_manager::bundled_models_response; use codex_models_manager::manager::RefreshStrategy; @@ -24,8 +26,6 @@ use codex_protocol::openai_models::default_input_modalities; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadSettingsOverrides; use codex_protocol::user_input::UserInput; use core_test_support::responses::ev_completed_with_tokens; diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index 136996723e..fff66362b9 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -7,6 +7,8 @@ use codex_core::config::CurrentTimeReminderConfig; use codex_extension_items::ExtensionItem; use codex_extension_items::sleep::SleepItem; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::AgentPath; use codex_protocol::config_types::CollaborationMode; use codex_protocol::config_types::ModeKind; @@ -17,8 +19,6 @@ use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadSettingsOverrides; use codex_protocol::user_input::UserInput; use core_test_support::context_snapshot; diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index 19041c5acb..df654432c0 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -3,6 +3,8 @@ use anyhow::Result; use chrono::Utc; use codex_config::config_toml::RealtimeWsVersion; use codex_core::test_support::auth_manager_from_auth; +use codex_history::InitialHistory; +use codex_history::RolloutItem; use codex_login::CodexAuth; use codex_login::OPENAI_API_KEY_ENV_VAR; use codex_protocol::ThreadId; @@ -16,7 +18,6 @@ use codex_protocol::protocol::ConversationStartTransport; use codex_protocol::protocol::ConversationTextParams; use codex_protocol::protocol::ConversationTextRole; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::Op; use codex_protocol::protocol::RealtimeAudioFrame; use codex_protocol::protocol::RealtimeConversationRealtimeEvent; @@ -25,7 +26,6 @@ use codex_protocol::protocol::RealtimeEvent; use codex_protocol::protocol::RealtimeNoopRequested; use codex_protocol::protocol::RealtimeOutputModality; use codex_protocol::protocol::RealtimeVoice; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::user_input::UserInput; use core_test_support::responses; diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index d3f0f73a24..b8187490dc 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -30,6 +30,8 @@ use codex_extension_api::ThreadStartInput; use codex_extension_api::WorldStateContributionInput; use codex_extension_api::WorldStateSectionContribution; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_http_client::HttpClientFactory; use codex_http_client::OutboundProxyPolicy; use codex_protocol::capabilities::CapabilityRootLocation; @@ -49,8 +51,6 @@ use codex_protocol::protocol::ENVIRONMENTS_INSTRUCTIONS_OPEN_TAG; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; use codex_protocol::protocol::ReviewDecision; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::ThreadSettingsOverrides; use codex_protocol::protocol::TurnEnvironmentSelection; diff --git a/codex-rs/core/tests/suite/resume_warning.rs b/codex-rs/core/tests/suite/resume_warning.rs index 876b65c437..98333f1d8a 100644 --- a/codex-rs/core/tests/suite/resume_warning.rs +++ b/codex-rs/core/tests/suite/resume_warning.rs @@ -3,15 +3,15 @@ use std::sync::Arc; use codex_core::NewThread; +use codex_history::InitialHistory; +use codex_history::ResumedHistory; +use codex_history::RolloutItem; use codex_login::CodexAuth; use codex_protocol::ThreadId; use codex_protocol::config_types::ModeKind; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::mcp::ClientMcpExtensions; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; -use codex_protocol::protocol::ResumedHistory; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnContextItem; use codex_protocol::protocol::TurnStartedEvent; diff --git a/codex-rs/core/tests/suite/review.rs b/codex-rs/core/tests/suite/review.rs index 7264bea8da..98ed4018c7 100644 --- a/codex-rs/core/tests/suite/review.rs +++ b/codex-rs/core/tests/suite/review.rs @@ -5,6 +5,8 @@ use codex_core::config::Constrained; use codex_core::find_thread_path_by_id_str; use codex_exec_server::CreateDirectoryOptions; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::ServiceTier; use codex_protocol::items::TurnItem; @@ -26,8 +28,6 @@ use codex_protocol::protocol::ReviewLineRange; use codex_protocol::protocol::ReviewOutputEvent; use codex_protocol::protocol::ReviewRequest; use codex_protocol::protocol::ReviewTarget; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadSettingsOverrides; use codex_protocol::protocol::TurnEnvironmentSelections; use codex_protocol::review_format::render_review_output_text; diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index d23db10004..20574978b8 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -36,6 +36,7 @@ use codex_mcp::SandboxState; use codex_models_manager::manager::RefreshStrategy; use codex_utils_path_uri::LegacyAppPathString; +use codex_history::RolloutItem; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::models::ContentItem; use codex_protocol::models::PermissionProfile; @@ -54,7 +55,6 @@ use codex_protocol::protocol::McpStartupFailureReason; use codex_protocol::protocol::McpStartupStatus; use codex_protocol::protocol::McpToolCallBeginEvent; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; use codex_protocol::user_input::UserInput; use codex_utils_cargo_bin::cargo_bin; use codex_utils_path_uri::PathUri; diff --git a/codex-rs/core/tests/suite/spawn_agent_description.rs b/codex-rs/core/tests/suite/spawn_agent_description.rs index bebab31184..4d4dacf7ef 100644 --- a/codex-rs/core/tests/suite/spawn_agent_description.rs +++ b/codex-rs/core/tests/suite/spawn_agent_description.rs @@ -4,6 +4,8 @@ use anyhow::Result; use codex_core::config::AgentRoleConfig; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_models_manager::manager::RefreshStrategy; use codex_models_manager::manager::SharedModelsManager; @@ -18,8 +20,6 @@ use codex_protocol::openai_models::ReasoningEffortPreset; use codex_protocol::openai_models::TruncationPolicyConfig; use codex_protocol::openai_models::default_input_modalities; use codex_protocol::protocol::MULTI_AGENT_MODE_OPEN_TAG; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use core_test_support::responses::ev_completed; use core_test_support::responses::ev_response_created; use core_test_support::responses::mount_models_once; diff --git a/codex-rs/core/tests/suite/sqlite_state.rs b/codex-rs/core/tests/suite/sqlite_state.rs index fdc0dd8497..84ff379f31 100644 --- a/codex-rs/core/tests/suite/sqlite_state.rs +++ b/codex-rs/core/tests/suite/sqlite_state.rs @@ -5,6 +5,8 @@ use codex_core::StartThreadOptions; use codex_core::config::Config; use codex_extension_api::ExtensionRegistryBuilder; use codex_features::Feature; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::CodexAuth; use codex_protocol::ThreadId; use codex_protocol::config_types::WebSearchMode; @@ -16,8 +18,6 @@ use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/core/tests/suite/subagent_notifications.rs b/codex-rs/core/tests/suite/subagent_notifications.rs index 55547c97d2..246681dbbd 100644 --- a/codex-rs/core/tests/suite/subagent_notifications.rs +++ b/codex-rs/core/tests/suite/subagent_notifications.rs @@ -3,6 +3,7 @@ use codex_core::StartThreadOptions; use codex_core::ThreadConfigSnapshot; use codex_core::config::AgentRoleConfig; use codex_features::Feature; +use codex_history::RolloutItem; use codex_models_manager::bundled_models_response; use codex_protocol::ThreadId; use codex_protocol::config_types::ReasoningSummary; @@ -12,7 +13,6 @@ use codex_protocol::protocol::AgentStatus; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::ThreadHistoryMode; diff --git a/codex-rs/core/tests/suite/unstable_features_warning.rs b/codex-rs/core/tests/suite/unstable_features_warning.rs index c57b503281..552c70b5d8 100644 --- a/codex-rs/core/tests/suite/unstable_features_warning.rs +++ b/codex-rs/core/tests/suite/unstable_features_warning.rs @@ -3,10 +3,10 @@ use codex_config::CONFIG_TOML_FILE; use codex_core::NewThread; use codex_features::Feature; +use codex_history::InitialHistory; use codex_login::CodexAuth; use codex_protocol::mcp::ClientMcpExtensions; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::WarningEvent; use codex_utils_absolute_path::AbsolutePathBuf; use core::time::Duration; diff --git a/codex-rs/core/tests/suite/user_message_admission.rs b/codex-rs/core/tests/suite/user_message_admission.rs index 60f84a0d11..2d1a4f7fe2 100644 --- a/codex-rs/core/tests/suite/user_message_admission.rs +++ b/codex-rs/core/tests/suite/user_message_admission.rs @@ -1,13 +1,13 @@ use codex_core::UserMessageAdmission; use codex_core::config::Constrained; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_protocol::error::CodexErrorDetails; use codex_protocol::items::TurnItem; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::CodexErrorInfo; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::user_input::UserInput; use core_test_support::responses; diff --git a/codex-rs/exec/Cargo.toml b/codex-rs/exec/Cargo.toml index cdfc569b68..9c3a236bf7 100644 --- a/codex-rs/exec/Cargo.toml +++ b/codex-rs/exec/Cargo.toml @@ -32,6 +32,7 @@ codex-config = { workspace = true } codex-core = { workspace = true } codex-feedback = { workspace = true } codex-git-utils = { workspace = true } +codex-history = { workspace = true } codex-login = { workspace = true } codex-model-provider-info = { workspace = true } codex-otel = { workspace = true } diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs index 7d010d00f1..bee8ef7008 100644 --- a/codex-rs/exec/src/lib.rs +++ b/codex-rs/exec/src/lib.rs @@ -76,6 +76,8 @@ use codex_core::path_utils; use codex_core::read_session_meta_line; use codex_feedback::CodexFeedback; use codex_git_utils::get_git_repo_root; +use codex_history::RolloutItem; +use codex_history::RolloutLine; use codex_login::default_client::set_default_client_residency_requirement; use codex_login::default_client::set_default_originator; use codex_login::enforce_login_restrictions; @@ -92,8 +94,6 @@ use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::ReviewRequest; use codex_protocol::protocol::ReviewTarget; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionConfiguredEvent; use codex_protocol::protocol::SessionSource; use codex_protocol::user_input::UserInput; diff --git a/codex-rs/ext/goal/Cargo.toml b/codex-rs/ext/goal/Cargo.toml index f6ee92ce3a..22ee1794fd 100644 --- a/codex-rs/ext/goal/Cargo.toml +++ b/codex-rs/ext/goal/Cargo.toml @@ -19,6 +19,7 @@ codex-core = { workspace = true } codex-extension-api = { workspace = true } codex-otel = { workspace = true } codex-protocol = { workspace = true } +codex-rollout = { workspace = true } codex-state = { workspace = true } codex-tools = { workspace = true } codex-utils-template = { workspace = true } diff --git a/codex-rs/ext/goal/src/api.rs b/codex-rs/ext/goal/src/api.rs index fbd747b72e..83d58f7f01 100644 --- a/codex-rs/ext/goal/src/api.rs +++ b/codex-rs/ext/goal/src/api.rs @@ -7,11 +7,11 @@ use std::sync::Weak; use codex_protocol::ThreadId; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadGoal; use codex_protocol::protocol::ThreadGoalStatus; use codex_protocol::protocol::ThreadGoalUpdatedEvent; use codex_protocol::protocol::validate_thread_goal_objective; +use codex_rollout::RolloutItem; use crate::runtime::GoalRuntimeHandle; use crate::runtime::PreviousGoalSnapshot; diff --git a/codex-rs/external-agent-migration/src/sessions/append.rs b/codex-rs/external-agent-migration/src/sessions/append.rs index 4437dd29eb..7cc4dabeb5 100644 --- a/codex-rs/external-agent-migration/src/sessions/append.rs +++ b/codex-rs/external-agent-migration/src/sessions/append.rs @@ -6,8 +6,8 @@ use codex_core::ThreadManager; use codex_protocol::ThreadId; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadMemoryMode; +use codex_rollout::RolloutItem; use codex_thread_store::AppendThreadItemsParams; use codex_thread_store::ReadThreadParams; use codex_thread_store::ResumeThreadParams; diff --git a/codex-rs/external-agent-migration/src/sessions/export.rs b/codex-rs/external-agent-migration/src/sessions/export.rs index c993664783..9f3d9dcac5 100644 --- a/codex-rs/external-agent-migration/src/sessions/export.rs +++ b/codex-rs/external-agent-migration/src/sessions/export.rs @@ -12,13 +12,13 @@ use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AgentMessageEvent; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::TokenCountEvent; use codex_protocol::protocol::TokenUsage; use codex_protocol::protocol::TokenUsageInfo; use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; +use codex_rollout::RolloutItem; use codex_utils_output_truncation::approx_tokens_from_byte_count_i64; use std::collections::BTreeSet; use std::io; diff --git a/codex-rs/external-agent-migration/src/sessions/mod.rs b/codex-rs/external-agent-migration/src/sessions/mod.rs index a9a8220574..8b31556e8e 100644 --- a/codex-rs/external-agent-migration/src/sessions/mod.rs +++ b/codex-rs/external-agent-migration/src/sessions/mod.rs @@ -9,7 +9,7 @@ pub(crate) mod records_cur; mod title; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutItem; +use codex_rollout::RolloutItem; use std::collections::BTreeSet; use std::io; use std::path::Path; diff --git a/codex-rs/history/BUILD.bazel b/codex-rs/history/BUILD.bazel new file mode 100644 index 0000000000..e3c0ef9e85 --- /dev/null +++ b/codex-rs/history/BUILD.bazel @@ -0,0 +1,6 @@ +load("//:defs.bzl", "codex_rust_crate") + +codex_rust_crate( + name = "history", + crate_name = "codex_history", +) diff --git a/codex-rs/history/Cargo.toml b/codex-rs/history/Cargo.toml new file mode 100644 index 0000000000..6188303226 --- /dev/null +++ b/codex-rs/history/Cargo.toml @@ -0,0 +1,23 @@ +[package] +edition.workspace = true +license.workspace = true +name = "codex-history" +version.workspace = true + +[lib] +doctest = false +name = "codex_history" +path = "src/lib.rs" + +[lints] +workspace = true + +[dependencies] +codex-protocol = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true, features = ["derive"] } + +[dev-dependencies] +anyhow = { workspace = true } +pretty_assertions = { workspace = true } +serde_json = { workspace = true } diff --git a/codex-rs/history/src/lib.rs b/codex-rs/history/src/lib.rs new file mode 100644 index 0000000000..8f9aa0a166 --- /dev/null +++ b/codex-rs/history/src/lib.rs @@ -0,0 +1,344 @@ +//! Model-history and persisted-rollout domain types. + +use std::path::PathBuf; +use std::sync::Arc; + +use codex_protocol::ThreadId; +use codex_protocol::capabilities::SelectedCapabilityRoot; +use codex_protocol::dynamic_tools::DynamicToolSpec; +use codex_protocol::models::BaseInstructions; +use codex_protocol::models::ContentItem; +use codex_protocol::models::ResponseItem; +use codex_protocol::protocol::EventMsg; +use codex_protocol::protocol::InterAgentCommunication; +use codex_protocol::protocol::MultiAgentVersion; +use codex_protocol::protocol::SessionMeta; +use codex_protocol::protocol::SessionMetaLine; +use codex_protocol::protocol::SessionSource; +use codex_protocol::protocol::ThreadHistoryMode; +use codex_protocol::protocol::ThreadSource; +use codex_protocol::protocol::TurnContextItem; +use codex_protocol::protocol::WorldStateItem; +use schemars::JsonSchema; +use serde::Deserialize; +use serde::Deserializer; +use serde::Serialize; + +/// Persisted rollout item used by core history and rollout storage. +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)] +#[serde(tag = "type", content = "payload", rename_all = "snake_case")] +pub enum RolloutItem { + SessionMeta(SessionMetaLine), + ResponseItem(ResponseItem), + InterAgentCommunication(InterAgentCommunication), + InterAgentCommunicationMetadata { trigger_turn: bool }, + Compacted(CompactedItem), + TurnContext(TurnContextItem), + WorldState(WorldStateItem), + EventMsg(EventMsg), +} + +#[derive(Serialize, Clone, Debug, PartialEq, JsonSchema)] +pub struct CompactedItem { + pub message: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub replacement_history: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub window_number: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub first_window_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub previous_window_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub window_id: Option, +} + +impl From for ResponseItem { + fn from(value: CompactedItem) -> Self { + ResponseItem::Message { + id: None, + role: "assistant".to_string(), + content: vec![ContentItem::OutputText { + text: value.message, + }], + phase: None, + internal_chat_message_metadata_passthrough: None, + } + } +} + +// Before window_number was introduced, the numeric window number was serialized as +// window_id. Accept that shape so existing rollouts remain resumable. +impl<'de> Deserialize<'de> for CompactedItem { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let serialized = SerializedCompactedItem::deserialize(deserializer)?; + let mut window_number = serialized.window_number; + let window_id = match serialized.window_id { + Some(SerializedWindowId::Id(window_id)) => Some(window_id), + Some(SerializedWindowId::LegacyWindowNumber(legacy_window_number)) => { + window_number.get_or_insert(legacy_window_number); + None + } + None => None, + }; + Ok(Self { + message: serialized.message, + replacement_history: serialized.replacement_history, + window_number, + first_window_id: serialized.first_window_id, + previous_window_id: serialized.previous_window_id, + window_id, + }) + } +} + +#[derive(Deserialize)] +struct SerializedCompactedItem { + message: String, + #[serde(default)] + replacement_history: Option>, + #[serde(default)] + window_number: Option, + #[serde(default)] + first_window_id: Option, + #[serde(default)] + previous_window_id: Option, + #[serde(default)] + window_id: Option, +} + +#[derive(Deserialize)] +#[serde(untagged)] +enum SerializedWindowId { + Id(String), + LegacyWindowNumber(u64), +} + +#[derive(Serialize, Deserialize, Clone, JsonSchema)] +pub struct RolloutLine { + pub timestamp: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ordinal: Option, + #[serde(flatten)] + pub item: RolloutItem, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ResumedHistory { + pub conversation_id: ThreadId, + pub history: Arc>, + pub rollout_path: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub enum InitialHistory { + New, + Cleared, + Resumed(ResumedHistory), + Forked(Vec), +} + +impl InitialHistory { + pub fn scan_rollout_items(&self, mut predicate: impl FnMut(&RolloutItem) -> bool) -> bool { + match self { + Self::New | Self::Cleared => false, + Self::Resumed(resumed) => resumed.history.iter().any(&mut predicate), + Self::Forked(items) => items.iter().any(predicate), + } + } + + pub fn forked_from_id(&self) -> Option { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => resumed.history.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => meta_line.meta.forked_from_id, + _ => None, + }), + Self::Forked(items) => items.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => Some(meta_line.meta.id), + _ => None, + }), + } + } + + pub fn session_cwd(&self) -> Option { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => session_cwd_from_items(&resumed.history), + Self::Forked(items) => session_cwd_from_items(items), + } + } + + pub fn get_rollout_items(&self) -> &[RolloutItem] { + match self { + Self::New | Self::Cleared => &[], + Self::Resumed(resumed) => &resumed.history, + Self::Forked(items) => items, + } + } + + pub fn get_event_msgs(&self) -> Option> { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => Some( + resumed + .history + .iter() + .filter_map(|item| match item { + RolloutItem::EventMsg(event) => Some(event.clone()), + _ => None, + }) + .collect(), + ), + Self::Forked(items) => Some( + items + .iter() + .filter_map(|item| match item { + RolloutItem::EventMsg(event) => Some(event.clone()), + _ => None, + }) + .collect(), + ), + } + } + + pub fn get_base_instructions(&self) -> Option { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => resumed.history.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => meta_line.meta.base_instructions.clone(), + _ => None, + }), + Self::Forked(items) => items.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => meta_line.meta.base_instructions.clone(), + _ => None, + }), + } + } + + pub fn get_dynamic_tools(&self) -> Option> { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => resumed.history.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => meta_line.meta.dynamic_tools.clone(), + _ => None, + }), + Self::Forked(items) => items.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => meta_line.meta.dynamic_tools.clone(), + _ => None, + }), + } + } + + pub fn get_selected_capability_roots(&self) -> Vec { + self.get_session_meta() + .map(|meta| meta.selected_capability_roots.clone()) + .unwrap_or_default() + } + + pub fn get_multi_agent_version(&self) -> Option { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => { + multi_agent_version_from_items(&resumed.history, Some(resumed.conversation_id)) + } + Self::Forked(items) => multi_agent_version_from_items(items, /*thread_id*/ None), + } + } + + pub fn get_history_mode(&self, default_history_mode: ThreadHistoryMode) -> ThreadHistoryMode { + match self { + Self::New | Self::Cleared => default_history_mode, + Self::Resumed(_) | Self::Forked(_) => self + .get_session_meta() + .map(|meta| meta.history_mode) + .unwrap_or(default_history_mode), + } + } + + pub fn get_resumed_session_sources(&self) -> Option<(SessionSource, Option)> { + let meta = self.get_resumed_session_meta()?; + Some((meta.source.clone(), meta.thread_source.clone())) + } + + pub fn get_resumed_thread_source(&self) -> Option { + self.get_resumed_session_meta() + .and_then(|meta| meta.thread_source.clone()) + } + + pub fn get_session_originator(&self) -> Option { + self.get_session_meta() + .map(|meta| meta.originator.clone()) + .filter(|originator| !originator.is_empty()) + } + + pub fn get_resumed_parent_thread_id(&self) -> Option { + self.get_resumed_session_meta() + .and_then(|meta| meta.parent_thread_id) + } + + fn get_session_meta(&self) -> Option<&SessionMeta> { + match self { + Self::New | Self::Cleared => None, + Self::Resumed(resumed) => resumed.history.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => Some(&meta_line.meta), + _ => None, + }), + Self::Forked(items) => items.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => Some(&meta_line.meta), + _ => None, + }), + } + } + + fn get_resumed_session_meta(&self) -> Option<&SessionMeta> { + match self { + Self::New | Self::Cleared | Self::Forked(_) => None, + Self::Resumed(resumed) => resumed.history.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => Some(&meta_line.meta), + _ => None, + }), + } + } +} + +fn session_cwd_from_items(items: &[RolloutItem]) -> Option { + items.iter().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) => Some(meta_line.meta.cwd.clone()), + _ => None, + }) +} + +fn multi_agent_version_from_items( + items: &[RolloutItem], + thread_id: Option, +) -> Option { + let session_meta_version = items.iter().rev().find_map(|item| match item { + RolloutItem::SessionMeta(meta_line) + if thread_id.is_none_or(|thread_id| meta_line.meta.id == thread_id) => + { + meta_line.meta.multi_agent_version + } + _ => None, + }); + + session_meta_version.or_else(|| { + items.iter().rev().find_map(|item| match item { + RolloutItem::TurnContext(turn_context) => turn_context.multi_agent_version, + RolloutItem::SessionMeta(_) + | RolloutItem::ResponseItem(_) + | RolloutItem::InterAgentCommunication(_) + | RolloutItem::InterAgentCommunicationMetadata { .. } + | RolloutItem::Compacted(_) + | RolloutItem::WorldState(_) + | RolloutItem::EventMsg(_) => None, + }) + }) +} + +#[cfg(test)] +#[path = "tests.rs"] +mod tests; diff --git a/codex-rs/history/src/tests.rs b/codex-rs/history/src/tests.rs new file mode 100644 index 0000000000..079f644f6e --- /dev/null +++ b/codex-rs/history/src/tests.rs @@ -0,0 +1,179 @@ +use anyhow::Result; +use pretty_assertions::assert_eq; +use serde_json::json; + +use super::*; + +#[test] +fn response_item_rollout_line_preserves_shape() -> Result<()> { + let legacy_line = json!({ + "timestamp": "2025-01-03T12:00:00.000Z", + "ordinal": 7, + "type": "response_item", + "payload": { + "type": "message", + "role": "user", + "content": [{ + "type": "input_text", + "text": "hello", + }], + }, + }); + + let line = serde_json::from_value::(legacy_line.clone())?; + let RolloutItem::ResponseItem(item) = &line.item else { + panic!("expected response item"); + }; + assert!(matches!(item, ResponseItem::Message { .. })); + assert_eq!(serde_json::to_value(line)?, legacy_line); + Ok(()) +} + +#[test] +fn response_item_replacement_history_preserves_shape() -> Result<()> { + let legacy_item = json!({ + "message": "summary", + "replacement_history": [{ + "type": "message", + "role": "user", + "content": [{ + "type": "input_text", + "text": "hello", + }], + }], + }); + + let item = serde_json::from_value::(legacy_item.clone())?; + let replacement_history = item + .replacement_history + .as_ref() + .expect("replacement history"); + assert!(matches!( + &replacement_history[0], + ResponseItem::Message { .. } + )); + assert_eq!(serde_json::to_value(item)?, legacy_item); + Ok(()) +} + +#[test] +fn compacted_item_serializes_window_number_and_id() -> Result<()> { + let item = CompactedItem { + message: "summary".to_string(), + replacement_history: None, + window_number: Some(3), + first_window_id: Some("019b3f6e-0000-7000-8000-000000000001".to_string()), + previous_window_id: Some("019b3f6e-0000-7000-8000-000000000002".to_string()), + window_id: Some("019b3f6e-7a10-7cc3-8b6e-1d09e2f7a001".to_string()), + }; + + assert_eq!( + serde_json::to_value(item)?, + json!({ + "message": "summary", + "window_number": 3, + "first_window_id": "019b3f6e-0000-7000-8000-000000000001", + "previous_window_id": "019b3f6e-0000-7000-8000-000000000002", + "window_id": "019b3f6e-7a10-7cc3-8b6e-1d09e2f7a001", + }) + ); + Ok(()) +} + +#[test] +fn compacted_item_migrates_legacy_numeric_window_id() -> Result<()> { + let item = serde_json::from_value::(json!({ + "message": "summary", + "window_id": 3, + }))?; + + assert_eq!( + item, + CompactedItem { + message: "summary".to_string(), + replacement_history: None, + window_number: Some(3), + first_window_id: None, + previous_window_id: None, + window_id: None, + } + ); + Ok(()) +} + +#[test] +fn copied_history_uses_persisted_history_mode() -> Result<()> { + let thread_id = ThreadId::from_string("00000000-0000-0000-0000-000000000001")?; + let session_meta = RolloutItem::SessionMeta(SessionMetaLine { + meta: SessionMeta { + session_id: thread_id.into(), + id: thread_id, + history_mode: ThreadHistoryMode::Legacy, + ..SessionMeta::default() + }, + git: None, + }); + let history = InitialHistory::Resumed(ResumedHistory { + conversation_id: thread_id, + history: Arc::new(vec![session_meta.clone()]), + rollout_path: None, + }); + + assert_eq!( + history.get_history_mode(ThreadHistoryMode::Paginated), + ThreadHistoryMode::Legacy + ); + assert_eq!( + InitialHistory::Forked(vec![session_meta]).get_history_mode(ThreadHistoryMode::Paginated), + ThreadHistoryMode::Legacy + ); + assert_eq!( + InitialHistory::New.get_history_mode(ThreadHistoryMode::Paginated), + ThreadHistoryMode::Paginated + ); + assert_eq!( + InitialHistory::Resumed(ResumedHistory { + conversation_id: thread_id, + history: Arc::new(Vec::new()), + rollout_path: None, + }) + .get_history_mode(ThreadHistoryMode::Paginated), + ThreadHistoryMode::Paginated + ); + Ok(()) +} + +#[test] +fn multi_agent_version_uses_newest_present_session_meta_value() -> Result<()> { + let thread_id = ThreadId::from_string("67e55044-10b1-426f-9247-bb680e5fe0c8")?; + let older_meta = SessionMetaLine { + meta: SessionMeta { + session_id: thread_id.into(), + id: thread_id, + multi_agent_version: Some(MultiAgentVersion::V2), + ..Default::default() + }, + git: None, + }; + let newer_meta_without_version = SessionMetaLine { + meta: SessionMeta { + session_id: thread_id.into(), + id: thread_id, + multi_agent_version: None, + ..Default::default() + }, + git: None, + }; + + assert_eq!( + multi_agent_version_from_items( + &[ + RolloutItem::SessionMeta(older_meta), + RolloutItem::SessionMeta(newer_meta_without_version), + ], + Some(thread_id), + ), + Some(MultiAgentVersion::V2) + ); + Ok(()) +} diff --git a/codex-rs/memories/write/src/phase1.rs b/codex-rs/memories/write/src/phase1.rs index f54646dd11..ac0684a132 100644 --- a/codex-rs/memories/write/src/phase1.rs +++ b/codex-rs/memories/write/src/phase1.rs @@ -13,9 +13,9 @@ use codex_protocol::error::CodexErr; use codex_protocol::models::BaseInstructions; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::TokenUsage; use codex_rollout::INTERACTIVE_SESSION_SOURCES; +use codex_rollout::RolloutItem; use codex_rollout::should_persist_response_item_for_memories; use codex_secrets::redact_secrets; use futures::StreamExt; diff --git a/codex-rs/memories/write/src/startup_tests.rs b/codex-rs/memories/write/src/startup_tests.rs index 853ba3a2c4..7cb3d4bc78 100644 --- a/codex-rs/memories/write/src/startup_tests.rs +++ b/codex-rs/memories/write/src/startup_tests.rs @@ -26,9 +26,9 @@ use codex_protocol::openai_models::ModelsResponse; use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use codex_state::Phase2JobClaimOutcome; use codex_utils_absolute_path::test_support::PathExt; use core_test_support::responses::ResponseMock; diff --git a/codex-rs/protocol/src/compacted_item.rs b/codex-rs/protocol/src/compacted_item.rs deleted file mode 100644 index 0f437e0bb6..0000000000 --- a/codex-rs/protocol/src/compacted_item.rs +++ /dev/null @@ -1,106 +0,0 @@ -use crate::models::ResponseItem; -use crate::protocol::CompactedItem; -use serde::Deserialize; - -// Before `window_number` was introduced, the numeric window number was serialized as -// `window_id`. Accept that shape so existing rollouts remain resumable. -impl<'de> Deserialize<'de> for CompactedItem { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let serialized = SerializedCompactedItem::deserialize(deserializer)?; - let mut window_number = serialized.window_number; - let window_id = match serialized.window_id { - Some(SerializedWindowId::Id(window_id)) => Some(window_id), - Some(SerializedWindowId::LegacyWindowNumber(legacy_window_number)) => { - window_number.get_or_insert(legacy_window_number); - None - } - None => None, - }; - Ok(Self { - message: serialized.message, - replacement_history: serialized.replacement_history, - window_number, - first_window_id: serialized.first_window_id, - previous_window_id: serialized.previous_window_id, - window_id, - }) - } -} - -#[derive(Deserialize)] -struct SerializedCompactedItem { - message: String, - #[serde(default)] - replacement_history: Option>, - #[serde(default)] - window_number: Option, - #[serde(default)] - first_window_id: Option, - #[serde(default)] - previous_window_id: Option, - #[serde(default)] - window_id: Option, -} - -#[derive(Deserialize)] -#[serde(untagged)] -enum SerializedWindowId { - Id(String), - LegacyWindowNumber(u64), -} - -#[cfg(test)] -mod tests { - use super::*; - use anyhow::Result; - use pretty_assertions::assert_eq; - use serde_json::json; - - #[test] - fn serializes_window_number_and_id() -> Result<()> { - let item = CompactedItem { - message: "summary".to_string(), - replacement_history: None, - window_number: Some(3), - first_window_id: Some("019b3f6e-0000-7000-8000-000000000001".to_string()), - previous_window_id: Some("019b3f6e-0000-7000-8000-000000000002".to_string()), - window_id: Some("019b3f6e-7a10-7cc3-8b6e-1d09e2f7a001".to_string()), - }; - - assert_eq!( - serde_json::to_value(item)?, - json!({ - "message": "summary", - "window_number": 3, - "first_window_id": "019b3f6e-0000-7000-8000-000000000001", - "previous_window_id": "019b3f6e-0000-7000-8000-000000000002", - "window_id": "019b3f6e-7a10-7cc3-8b6e-1d09e2f7a001", - }) - ); - Ok(()) - } - - #[test] - fn migrates_legacy_numeric_window_id() -> Result<()> { - let item = serde_json::from_value::(json!({ - "message": "summary", - "window_id": 3, - }))?; - - assert_eq!( - item, - CompactedItem { - message: "summary".to_string(), - replacement_history: None, - window_number: Some(3), - first_window_id: None, - previous_window_id: None, - window_id: None, - } - ); - Ok(()) - } -} diff --git a/codex-rs/protocol/src/lib.rs b/codex-rs/protocol/src/lib.rs index 28fff2120a..c34828c3f1 100644 --- a/codex-rs/protocol/src/lib.rs +++ b/codex-rs/protocol/src/lib.rs @@ -13,7 +13,6 @@ pub use tool_name::DEFAULT_FUNCTION_NAMESPACE; pub use tool_name::ToolName; pub mod approvals; pub mod capabilities; -mod compacted_item; pub mod config_types; pub mod dynamic_tools; pub mod error; diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index 48f0d36567..4398896b3f 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -10,7 +10,6 @@ use std::ops::Mul; use std::path::Path; use std::path::PathBuf; use std::str::FromStr; -use std::sync::Arc; use std::time::Duration; use strum_macros::EnumIter; @@ -2564,207 +2563,6 @@ pub struct ConversationPathResponseEvent { pub path: PathBuf, } -#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)] -pub struct ResumedHistory { - pub conversation_id: ThreadId, - pub history: Arc>, - pub rollout_path: Option, -} - -#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)] -pub enum InitialHistory { - New, - Cleared, - Resumed(ResumedHistory), - Forked(Vec), -} - -impl InitialHistory { - pub fn scan_rollout_items(&self, mut predicate: impl FnMut(&RolloutItem) -> bool) -> bool { - match self { - InitialHistory::New | InitialHistory::Cleared => false, - InitialHistory::Resumed(resumed) => resumed.history.iter().any(&mut predicate), - InitialHistory::Forked(items) => items.iter().any(predicate), - } - } - - pub fn forked_from_id(&self) -> Option { - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => { - resumed.history.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => meta_line.meta.forked_from_id, - _ => None, - }) - } - InitialHistory::Forked(items) => items.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => Some(meta_line.meta.id), - _ => None, - }), - } - } - - pub fn session_cwd(&self) -> Option { - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => session_cwd_from_items(&resumed.history), - InitialHistory::Forked(items) => session_cwd_from_items(items), - } - } - - pub fn get_rollout_items(&self) -> &[RolloutItem] { - match self { - InitialHistory::New | InitialHistory::Cleared => &[], - InitialHistory::Resumed(resumed) => &resumed.history, - InitialHistory::Forked(items) => items, - } - } - - pub fn get_event_msgs(&self) -> Option> { - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => Some( - resumed - .history - .iter() - .filter_map(|ri| match ri { - RolloutItem::EventMsg(ev) => Some(ev.clone()), - _ => None, - }) - .collect(), - ), - InitialHistory::Forked(items) => Some( - items - .iter() - .filter_map(|ri| match ri { - RolloutItem::EventMsg(ev) => Some(ev.clone()), - _ => None, - }) - .collect(), - ), - } - } - - pub fn get_base_instructions(&self) -> Option { - // TODO: SessionMeta should (in theory) always be first in the history, so we can probably only check the first item? - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => { - resumed.history.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => meta_line.meta.base_instructions.clone(), - _ => None, - }) - } - InitialHistory::Forked(items) => items.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => meta_line.meta.base_instructions.clone(), - _ => None, - }), - } - } - - pub fn get_dynamic_tools(&self) -> Option> { - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => { - resumed.history.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => meta_line.meta.dynamic_tools.clone(), - _ => None, - }) - } - InitialHistory::Forked(items) => items.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => meta_line.meta.dynamic_tools.clone(), - _ => None, - }), - } - } - - pub fn get_selected_capability_roots(&self) -> Vec { - self.get_session_meta() - .map(|meta| meta.selected_capability_roots.clone()) - .unwrap_or_default() - } - - pub fn get_multi_agent_version(&self) -> Option { - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => { - multi_agent_version_from_items(&resumed.history, Some(resumed.conversation_id)) - } - InitialHistory::Forked(items) => { - multi_agent_version_from_items(items, /*thread_id*/ None) - } - } - } - - pub fn get_history_mode(&self, default_history_mode: ThreadHistoryMode) -> ThreadHistoryMode { - match self { - InitialHistory::New | InitialHistory::Cleared => default_history_mode, - // Forks copy their source rollout items as-is, so they must keep - // the source format instead of converting to the destination default. - InitialHistory::Resumed(_) | InitialHistory::Forked(_) => self - .get_session_meta() - .map(|meta| meta.history_mode) - .unwrap_or(default_history_mode), - } - } - - pub fn get_resumed_session_sources(&self) -> Option<(SessionSource, Option)> { - let meta = self.get_resumed_session_meta()?; - Some((meta.source.clone(), meta.thread_source.clone())) - } - - pub fn get_resumed_thread_source(&self) -> Option { - self.get_resumed_session_meta() - .and_then(|meta| meta.thread_source.clone()) - } - - pub fn get_session_originator(&self) -> Option { - self.get_session_meta() - .map(|meta| meta.originator.clone()) - .filter(|originator| !originator.is_empty()) - } - - pub fn get_resumed_parent_thread_id(&self) -> Option { - self.get_resumed_session_meta() - .and_then(|meta| meta.parent_thread_id) - } - - fn get_session_meta(&self) -> Option<&SessionMeta> { - match self { - InitialHistory::New | InitialHistory::Cleared => None, - InitialHistory::Resumed(resumed) => { - resumed.history.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => Some(&meta_line.meta), - _ => None, - }) - } - InitialHistory::Forked(items) => items.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => Some(&meta_line.meta), - _ => None, - }), - } - } - - fn get_resumed_session_meta(&self) -> Option<&SessionMeta> { - match self { - InitialHistory::New | InitialHistory::Cleared | InitialHistory::Forked(_) => None, - InitialHistory::Resumed(resumed) => { - resumed.history.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => Some(&meta_line.meta), - _ => None, - }) - } - } - } -} - -fn session_cwd_from_items(items: &[RolloutItem]) -> Option { - items.iter().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) => Some(meta_line.meta.cwd.clone()), - _ => None, - }) -} - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)] #[serde(rename_all = "lowercase")] #[ts(rename_all = "lowercase")] @@ -3017,33 +2815,6 @@ impl fmt::Display for InternalSessionSource { } } -fn multi_agent_version_from_items( - items: &[RolloutItem], - thread_id: Option, -) -> Option { - let session_meta_version = items.iter().rev().find_map(|item| match item { - RolloutItem::SessionMeta(meta_line) - if thread_id.is_none_or(|thread_id| meta_line.meta.id == thread_id) => - { - meta_line.meta.multi_agent_version - } - _ => None, - }); - - session_meta_version.or_else(|| { - items.iter().rev().find_map(|item| match item { - RolloutItem::TurnContext(turn_context) => turn_context.multi_agent_version, - RolloutItem::SessionMeta(_) - | RolloutItem::ResponseItem(_) - | RolloutItem::InterAgentCommunication(_) - | RolloutItem::InterAgentCommunicationMetadata { .. } - | RolloutItem::Compacted(_) - | RolloutItem::WorldState(_) - | RolloutItem::EventMsg(_) => None, - }) - }) -} - #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "snake_case")] #[ts(rename_all = "snake_case")] @@ -3208,23 +2979,6 @@ impl<'de> Deserialize<'de> for SessionMetaLine { } } -#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS)] -#[serde(tag = "type", content = "payload", rename_all = "snake_case")] -pub enum RolloutItem { - SessionMeta(SessionMetaLine), - ResponseItem(ResponseItem), - /// Legacy delivery item reconstructed as a model-visible `agent_message`. - InterAgentCommunication(InterAgentCommunication), - /// Local delivery metadata that is not part of the Responses API item. - InterAgentCommunicationMetadata { - trigger_turn: bool, - }, - Compacted(CompactedItem), - TurnContext(TurnContextItem), - WorldState(WorldStateItem), - EventMsg(EventMsg), -} - /// Persisted comparison state used to resume model-visible world-state diffing. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, TS)] pub struct WorldStateItem { @@ -3243,39 +2997,6 @@ impl WorldStateItem { } } -#[derive(Serialize, Clone, Debug, PartialEq, JsonSchema, TS)] -pub struct CompactedItem { - pub message: String, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub replacement_history: Option>, - /// Monotonic position of this context window within the thread. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub window_number: Option, - /// UUIDv7 identity of the first context window in this thread's window chain. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub first_window_id: Option, - /// UUIDv7 identity of the context window immediately before this one. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub previous_window_id: Option, - /// UUIDv7 identity of this context window. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub window_id: Option, -} - -impl From for ResponseItem { - fn from(value: CompactedItem) -> Self { - ResponseItem::Message { - id: None, - role: "assistant".to_string(), - content: vec![ContentItem::OutputText { - text: value.message, - }], - phase: None, - internal_chat_message_metadata_passthrough: None, - } - } -} - #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS)] pub struct TurnContextNetworkItem { pub allowed_domains: Vec, @@ -3403,15 +3124,6 @@ impl Mul for TruncationPolicy { } } -#[derive(Serialize, Deserialize, Clone, JsonSchema)] -pub struct RolloutLine { - pub timestamp: String, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub ordinal: Option, - #[serde(flatten)] - pub item: RolloutItem, -} - #[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, TS)] pub struct GitInfo { /// Current commit hash (SHA) @@ -6006,49 +5718,6 @@ mod tests { Ok(()) } - #[test] - fn copied_history_uses_persisted_history_mode() -> Result<()> { - let thread_id = ThreadId::from_string("00000000-0000-0000-0000-000000000001")?; - let session_meta = RolloutItem::SessionMeta(SessionMetaLine { - meta: SessionMeta { - session_id: thread_id.into(), - id: thread_id, - history_mode: ThreadHistoryMode::Legacy, - ..SessionMeta::default() - }, - git: None, - }); - let history = InitialHistory::Resumed(ResumedHistory { - conversation_id: thread_id, - history: Arc::new(vec![session_meta.clone()]), - rollout_path: None, - }); - - assert_eq!( - history.get_history_mode(ThreadHistoryMode::Paginated), - ThreadHistoryMode::Legacy - ); - assert_eq!( - InitialHistory::Forked(vec![session_meta]) - .get_history_mode(ThreadHistoryMode::Paginated), - ThreadHistoryMode::Legacy - ); - assert_eq!( - InitialHistory::New.get_history_mode(ThreadHistoryMode::Paginated), - ThreadHistoryMode::Paginated - ); - assert_eq!( - InitialHistory::Resumed(ResumedHistory { - conversation_id: thread_id, - history: Arc::new(Vec::new()), - rollout_path: None, - }) - .get_history_mode(ThreadHistoryMode::Paginated), - ThreadHistoryMode::Paginated - ); - Ok(()) - } - #[test] fn turn_context_item_deserializes_without_network() -> Result<()> { let item: TurnContextItem = serde_json::from_value(json!({ @@ -6079,41 +5748,6 @@ mod tests { Ok(()) } - #[test] - fn multi_agent_version_uses_newest_present_session_meta_value() -> Result<()> { - let thread_id = ThreadId::from_string("67e55044-10b1-426f-9247-bb680e5fe0c8")?; - let older_meta = SessionMetaLine { - meta: SessionMeta { - session_id: thread_id.into(), - id: thread_id, - multi_agent_version: Some(MultiAgentVersion::V2), - ..Default::default() - }, - git: None, - }; - let newer_meta_without_version = SessionMetaLine { - meta: SessionMeta { - session_id: thread_id.into(), - id: thread_id, - multi_agent_version: None, - ..Default::default() - }, - git: None, - }; - - assert_eq!( - multi_agent_version_from_items( - &[ - RolloutItem::SessionMeta(older_meta), - RolloutItem::SessionMeta(newer_meta_without_version), - ], - Some(thread_id), - ), - Some(MultiAgentVersion::V2) - ); - Ok(()) - } - #[test] fn turn_context_item_serializes_network_when_present() -> Result<()> { let item = TurnContextItem { diff --git a/codex-rs/rollout/Cargo.toml b/codex-rs/rollout/Cargo.toml index 13d379c117..1bb4b54f14 100644 --- a/codex-rs/rollout/Cargo.toml +++ b/codex-rs/rollout/Cargo.toml @@ -18,6 +18,7 @@ chrono = { workspace = true, features = ["serde"] } codex-extension-items = { workspace = true } codex-file-search = { workspace = true } codex-git-utils = { workspace = true } +codex-history = { workspace = true } codex-otel = { workspace = true } codex-protocol = { workspace = true } codex-state = { workspace = true } diff --git a/codex-rs/rollout/src/compression_tests.rs b/codex-rs/rollout/src/compression_tests.rs index be0aa7895c..94ecebc12a 100644 --- a/codex-rs/rollout/src/compression_tests.rs +++ b/codex-rs/rollout/src/compression_tests.rs @@ -6,12 +6,12 @@ use std::os::unix::fs::PermissionsExt; use std::time::Duration; use std::time::SystemTime; +use crate::InitialHistory; +use crate::RolloutItem; +use crate::RolloutLine; use codex_protocol::ThreadId; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::InitialHistory; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/rollout/src/lib.rs b/codex-rs/rollout/src/lib.rs index 3618ecf8ac..b5713bfd80 100644 --- a/codex-rs/rollout/src/lib.rs +++ b/codex-rs/rollout/src/lib.rs @@ -21,6 +21,11 @@ pub(crate) mod session_index; mod sqlite_metrics; pub mod state_db; +pub use codex_history::CompactedItem; +pub use codex_history::InitialHistory; +pub use codex_history::ResumedHistory; +pub use codex_history::RolloutItem; +pub use codex_history::RolloutLine; pub(crate) use codex_protocol::protocol; pub const SESSIONS_SUBDIR: &str = "sessions"; diff --git a/codex-rs/rollout/src/list.rs b/codex-rs/rollout/src/list.rs index 376e54a24f..33b0560819 100644 --- a/codex-rs/rollout/src/list.rs +++ b/codex-rs/rollout/src/list.rs @@ -18,13 +18,13 @@ use uuid::Uuid; use super::ARCHIVED_SESSIONS_SUBDIR; use super::SESSIONS_SUBDIR; use super::compression; +use crate::RolloutItem; +use crate::RolloutLine; use crate::protocol::EventMsg; use crate::state_db; use codex_file_search as file_search; use codex_protocol::ThreadId; use codex_protocol::items::TurnItem; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; diff --git a/codex-rs/rollout/src/metadata.rs b/codex-rs/rollout/src/metadata.rs index b62e1e463d..99fd4d9d93 100644 --- a/codex-rs/rollout/src/metadata.rs +++ b/codex-rs/rollout/src/metadata.rs @@ -1,4 +1,5 @@ use crate::ARCHIVED_SESSIONS_SUBDIR; +use crate::RolloutItem; use crate::SESSIONS_SUBDIR; use crate::compression; use crate::list::parse_timestamp_uuid_from_filename; @@ -10,7 +11,6 @@ use chrono::Timelike; use chrono::Utc; use codex_protocol::ThreadId; use codex_protocol::protocol::AskForApproval; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/rollout/src/metadata_tests.rs b/codex-rs/rollout/src/metadata_tests.rs index cce72a642d..58f8fbdeef 100644 --- a/codex-rs/rollout/src/metadata_tests.rs +++ b/codex-rs/rollout/src/metadata_tests.rs @@ -1,15 +1,15 @@ #![allow(warnings, clippy::all)] use super::*; +use crate::CompactedItem; +use crate::RolloutItem; +use crate::RolloutLine; use chrono::DateTime; use chrono::NaiveDateTime; use chrono::Timelike; use chrono::Utc; use codex_protocol::ThreadId; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::GitInfo; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/rollout/src/model_context.rs b/codex-rs/rollout/src/model_context.rs index 45fc5de6bf..f333689b35 100644 --- a/codex-rs/rollout/src/model_context.rs +++ b/codex-rs/rollout/src/model_context.rs @@ -1,8 +1,8 @@ +use crate::RolloutItem; use codex_protocol::items::TurnItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::InterAgentCommunication; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionMetaLine; /// Whether a reverse model-context scan needs more rollout items. diff --git a/codex-rs/rollout/src/ordinal.rs b/codex-rs/rollout/src/ordinal.rs index 2d2fea6a76..14483ce706 100644 --- a/codex-rs/rollout/src/ordinal.rs +++ b/codex-rs/rollout/src/ordinal.rs @@ -6,9 +6,9 @@ use std::io::Seek; use std::io::SeekFrom; use std::path::Path; +use crate::RolloutItem; +use crate::RolloutLine; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadHistoryMode; use crate::reverse_jsonl_scanner::ReverseJsonlScanner; diff --git a/codex-rs/rollout/src/persistence_metrics.rs b/codex-rs/rollout/src/persistence_metrics.rs index d2b4db188a..3f1bc15756 100644 --- a/codex-rs/rollout/src/persistence_metrics.rs +++ b/codex-rs/rollout/src/persistence_metrics.rs @@ -2,12 +2,12 @@ use std::io::Write; use std::sync::Arc; use std::sync::Mutex; +use crate::RolloutItem; use codex_otel::MetricsClient; use codex_protocol::ThreadId; use codex_protocol::items::TurnItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadHistoryMode; use crate::policy::is_persisted_rollout_item; diff --git a/codex-rs/rollout/src/persistence_metrics_tests.rs b/codex-rs/rollout/src/persistence_metrics_tests.rs index 46f70bdf84..f53c0bb1f1 100644 --- a/codex-rs/rollout/src/persistence_metrics_tests.rs +++ b/codex-rs/rollout/src/persistence_metrics_tests.rs @@ -1,3 +1,4 @@ +use crate::RolloutItem; use codex_protocol::ThreadId; use codex_protocol::items::EnteredReviewModeItem; use codex_protocol::items::ExitedReviewModeItem; @@ -10,7 +11,6 @@ use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ExitedReviewModeEvent; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::ReviewTarget; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::TurnAbortReason; use codex_protocol::protocol::TurnAbortedEvent; diff --git a/codex-rs/rollout/src/policy.rs b/codex-rs/rollout/src/policy.rs index 22718f6c95..345da9e7f1 100644 --- a/codex-rs/rollout/src/policy.rs +++ b/codex-rs/rollout/src/policy.rs @@ -1,5 +1,5 @@ +use crate::RolloutItem; use crate::protocol::EventMsg; -use crate::protocol::RolloutItem; use codex_extension_items::ExtensionItem; use codex_protocol::items::TurnItem; use codex_protocol::models::ResponseItem; diff --git a/codex-rs/rollout/src/recorder.rs b/codex-rs/rollout/src/recorder.rs index 8c1dd81c37..aa210c2ba9 100644 --- a/codex-rs/rollout/src/recorder.rs +++ b/codex-rs/rollout/src/recorder.rs @@ -52,6 +52,10 @@ use super::metadata; use super::ordinal::RolloutOrdinalState; use super::ordinal::ordinal_state_for_rollout; use super::session_index::find_thread_names_by_ids; +use crate::InitialHistory; +use crate::ResumedHistory; +use crate::RolloutItem; +use crate::RolloutLine; use crate::config::RolloutConfigView; use crate::state_db; use crate::state_db::StateDbHandle; @@ -59,11 +63,7 @@ use codex_git_utils::collect_git_info; use codex_git_utils::get_git_repo_root; use codex_protocol::protocol::GitInfo as ProtocolGitInfo; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::MultiAgentVersion; -use codex_protocol::protocol::ResumedHistory; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionContextWindow; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; diff --git a/codex-rs/rollout/src/recorder_tests.rs b/codex-rs/rollout/src/recorder_tests.rs index f3394be5bf..7279a73e34 100644 --- a/codex-rs/rollout/src/recorder_tests.rs +++ b/codex-rs/rollout/src/recorder_tests.rs @@ -1,6 +1,8 @@ #![allow(warnings, clippy::all)] use super::*; +use crate::RolloutItem; +use crate::RolloutLine; use crate::config::RolloutConfig; use chrono::TimeZone; use codex_protocol::SessionId; @@ -10,8 +12,6 @@ use codex_protocol::protocol::AgentMessageEvent; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; diff --git a/codex-rs/rollout/src/search.rs b/codex-rs/rollout/src/search.rs index dc11ff0bc0..d292b24d33 100644 --- a/codex-rs/rollout/src/search.rs +++ b/codex-rs/rollout/src/search.rs @@ -5,11 +5,11 @@ use std::path::Path; use std::path::PathBuf; use std::process::Stdio; +use crate::RolloutItem; +use crate::RolloutLine; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::strip_user_message_prefix; use regex::Regex; use regex::RegexBuilder; diff --git a/codex-rs/rollout/src/session_index_tests.rs b/codex-rs/rollout/src/session_index_tests.rs index 0cc20e33b2..419701e537 100644 --- a/codex-rs/rollout/src/session_index_tests.rs +++ b/codex-rs/rollout/src/session_index_tests.rs @@ -1,8 +1,8 @@ #![allow(warnings, clippy::all)] use super::*; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; +use crate::RolloutItem; +use crate::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/rollout/src/state_db.rs b/codex-rs/rollout/src/state_db.rs index b0e8bb6427..f2ab6f20e3 100644 --- a/codex-rs/rollout/src/state_db.rs +++ b/codex-rs/rollout/src/state_db.rs @@ -1,3 +1,4 @@ +use crate::RolloutItem; use crate::config::RolloutConfig; use crate::config::RolloutConfigView; use crate::list::Cursor; @@ -9,7 +10,6 @@ use anyhow::Context; use chrono::DateTime; use chrono::Utc; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; pub use codex_state::LogEntry; diff --git a/codex-rs/rollout/src/state_db_tests.rs b/codex-rs/rollout/src/state_db_tests.rs index 36216ffa50..c9e8e28d92 100644 --- a/codex-rs/rollout/src/state_db_tests.rs +++ b/codex-rs/rollout/src/state_db_tests.rs @@ -1,13 +1,13 @@ #![allow(warnings, clippy::all)] use super::*; +use crate::RolloutLine; use crate::list::parse_cursor; use chrono::DateTime; use chrono::NaiveDateTime; use chrono::Timelike; use chrono::Utc; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::ThreadHistoryMode; diff --git a/codex-rs/rollout/src/tests.rs b/codex-rs/rollout/src/tests.rs index 5a7d0c1b9a..2918804e91 100644 --- a/codex-rs/rollout/src/tests.rs +++ b/codex-rs/rollout/src/tests.rs @@ -20,6 +20,8 @@ use time::macros::format_description; use uuid::Uuid; use crate::INTERACTIVE_SESSION_SOURCES; +use crate::RolloutItem; +use crate::RolloutLine; use crate::find_thread_path_by_id_str; use crate::list::Cursor; use crate::list::ThreadItem; @@ -33,8 +35,6 @@ use codex_protocol::ThreadId; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; diff --git a/codex-rs/state/Cargo.toml b/codex-rs/state/Cargo.toml index 560255a222..0d781fbff2 100644 --- a/codex-rs/state/Cargo.toml +++ b/codex-rs/state/Cargo.toml @@ -7,6 +7,7 @@ license.workspace = true [dependencies] anyhow = { workspace = true } chrono = { workspace = true } +codex-history = { workspace = true } codex-protocol = { workspace = true } codex-utils-absolute-path = { workspace = true } libsqlite3-sys = { workspace = true } diff --git a/codex-rs/state/src/extract.rs b/codex-rs/state/src/extract.rs index 9780ce3507..c60bdbdcb8 100644 --- a/codex-rs/state/src/extract.rs +++ b/codex-rs/state/src/extract.rs @@ -1,8 +1,8 @@ use crate::model::ThreadMetadata; +use codex_history::RolloutItem; use codex_protocol::items::TurnItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::TurnContextItem; use codex_protocol::protocol::UserMessageEvent; @@ -168,6 +168,7 @@ mod tests { use crate::model::ThreadMetadata; use chrono::DateTime; use chrono::Utc; + use codex_history::RolloutItem; use codex_protocol::ThreadId; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::CollaborationMode; @@ -183,7 +184,6 @@ mod tests { use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; - use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; diff --git a/codex-rs/state/src/runtime.rs b/codex-rs/state/src/runtime.rs index dd9c84a822..9029fdef6d 100644 --- a/codex-rs/state/src/runtime.rs +++ b/codex-rs/state/src/runtime.rs @@ -23,8 +23,8 @@ use crate::telemetry::DbKind; use crate::telemetry::DbTelemetry; use chrono::DateTime; use chrono::Utc; +use codex_history::RolloutItem; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutItem; use serde_json::Value; use sqlx::QueryBuilder; use sqlx::Row; diff --git a/codex-rs/thread-store/src/in_memory.rs b/codex-rs/thread-store/src/in_memory.rs index bca9e07df9..c8235f0f7f 100644 --- a/codex-rs/thread-store/src/in_memory.rs +++ b/codex-rs/thread-store/src/in_memory.rs @@ -11,12 +11,12 @@ use chrono::Utc; use codex_protocol::ThreadId; use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionContextWindow; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode; +use codex_rollout::RolloutItem; use codex_rollout::persisted_rollout_items; use crate::AppendThreadItemsParams; diff --git a/codex-rs/thread-store/src/live_thread.rs b/codex-rs/thread-store/src/live_thread.rs index 509671d80d..0052c7fd0b 100644 --- a/codex-rs/thread-store/src/live_thread.rs +++ b/codex-rs/thread-store/src/live_thread.rs @@ -2,9 +2,9 @@ use std::path::PathBuf; use std::sync::Arc; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode; +use codex_rollout::RolloutItem; use codex_rollout::RolloutPersistenceTelemetry; use codex_rollout::measure_and_filter_rollout_items; use codex_rollout::persisted_rollout_items; diff --git a/codex-rs/thread-store/src/local/live_writer.rs b/codex-rs/thread-store/src/local/live_writer.rs index fc54cea8c4..769a58ea03 100644 --- a/codex-rs/thread-store/src/local/live_writer.rs +++ b/codex-rs/thread-store/src/local/live_writer.rs @@ -1,10 +1,10 @@ use std::path::PathBuf; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode; use codex_rollout::RolloutConfig; +use codex_rollout::RolloutItem; use codex_rollout::RolloutRecorder; use codex_rollout::RolloutRecorderParams; use codex_rollout::persisted_rollout_items; diff --git a/codex-rs/thread-store/src/local/mod.rs b/codex-rs/thread-store/src/local/mod.rs index 9213acd5be..c58c16beee 100644 --- a/codex-rs/thread-store/src/local/mod.rs +++ b/codex-rs/thread-store/src/local/mod.rs @@ -573,7 +573,6 @@ mod tests { use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; - use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; @@ -582,6 +581,7 @@ mod tests { use codex_protocol::protocol::TurnContextItem; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; + use codex_rollout::RolloutItem; use tempfile::TempDir; use super::*; diff --git a/codex-rs/thread-store/src/local/model_context.rs b/codex-rs/thread-store/src/local/model_context.rs index 05d7bd6047..45fd1a9e76 100644 --- a/codex-rs/thread-store/src/local/model_context.rs +++ b/codex-rs/thread-store/src/local/model_context.rs @@ -2,13 +2,13 @@ use std::fs::File; use std::io; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::ThreadHistoryMode; use codex_rollout::ModelContextScan; use codex_rollout::ModelContextScanProgress; use codex_rollout::ReverseJsonlScanner; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use codex_rollout::ScanOutcome; use super::LocalThreadStore; diff --git a/codex-rs/thread-store/src/local/model_context_tests.rs b/codex-rs/thread-store/src/local/model_context_tests.rs index 26dca54cb7..882e3998f0 100644 --- a/codex-rs/thread-store/src/local/model_context_tests.rs +++ b/codex-rs/thread-store/src/local/model_context_tests.rs @@ -11,18 +11,18 @@ use codex_protocol::models::AgentMessageInputContent; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AskForApproval; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::HistoryPosition; use codex_protocol::protocol::ItemCompletedEvent; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnContextItem; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::user_input::UserInput; +use codex_rollout::CompactedItem; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use pretty_assertions::assert_eq; use tempfile::TempDir; use uuid::Uuid; diff --git a/codex-rs/thread-store/src/local/read_thread.rs b/codex-rs/thread-store/src/local/read_thread.rs index 2c2042281a..fa2a6621c7 100644 --- a/codex-rs/thread-store/src/local/read_thread.rs +++ b/codex-rs/thread-store/src/local/read_thread.rs @@ -327,7 +327,7 @@ async fn read_thread_from_rollout_path( pub(super) async fn load_history_items( path: &std::path::Path, -) -> ThreadStoreResult> { +) -> ThreadStoreResult> { let (items, _, _) = RolloutRecorder::load_rollout_items(path) .await .map_err(|err| ThreadStoreError::Internal { @@ -577,11 +577,11 @@ mod tests { use codex_protocol::items::UserMessageItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; - use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::user_input::UserInput; + use codex_rollout::RolloutItem; use codex_state::ThreadMetadataBuilder; use pretty_assertions::assert_eq; use tempfile::TempDir; diff --git a/codex-rs/thread-store/src/local/rollout_lineage_tests.rs b/codex-rs/thread-store/src/local/rollout_lineage_tests.rs index b44729e90f..c120d5a583 100644 --- a/codex-rs/thread-store/src/local/rollout_lineage_tests.rs +++ b/codex-rs/thread-store/src/local/rollout_lineage_tests.rs @@ -3,11 +3,11 @@ use std::path::Path; use codex_protocol::ThreadId; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::ThreadHistoryMode; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use pretty_assertions::assert_eq; use tempfile::TempDir; diff --git a/codex-rs/thread-store/src/local/rollout_migration.rs b/codex-rs/thread-store/src/local/rollout_migration.rs index 201c184607..aa70a0d6d8 100644 --- a/codex-rs/thread-store/src/local/rollout_migration.rs +++ b/codex-rs/thread-store/src/local/rollout_migration.rs @@ -16,12 +16,12 @@ use chrono::DateTime; use codex_app_server_protocol::project_rollout_line; use codex_protocol::ThreadId; use codex_protocol::protocol::InternalSessionSource; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadSource; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use serde::Serialize; use tokio::fs::File; use tokio::io::AsyncBufReadExt; diff --git a/codex-rs/thread-store/src/local/rollout_migration/canonicalizer.rs b/codex-rs/thread-store/src/local/rollout_migration/canonicalizer.rs index 87ce548d5d..5093ddef60 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/canonicalizer.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/canonicalizer.rs @@ -17,11 +17,11 @@ use codex_protocol::items::parse_hook_prompt_message; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnStartedEvent; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use std::collections::HashSet; use tokio::fs::File; use tokio::io::AsyncWriteExt; diff --git a/codex-rs/thread-store/src/local/rollout_migration/line_parser.rs b/codex-rs/thread-store/src/local/rollout_migration/line_parser.rs index dd71bcd8e5..4d004a533c 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/line_parser.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/line_parser.rs @@ -9,7 +9,7 @@ //! into paginated history. use chrono::DateTime; -use codex_protocol::protocol::RolloutLine; +use codex_rollout::RolloutLine; use codex_utils_path_uri::LegacyAppPathString; use codex_utils_path_uri::PathUri; use serde_json::Map; diff --git a/codex-rs/thread-store/src/local/rollout_migration/line_parser_tests.rs b/codex-rs/thread-store/src/local/rollout_migration/line_parser_tests.rs index ea1d31cbba..7992fba8f1 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/line_parser_tests.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/line_parser_tests.rs @@ -1,5 +1,5 @@ use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; +use codex_rollout::RolloutItem; use pretty_assertions::assert_eq; use serde_json::json; diff --git a/codex-rs/thread-store/src/local/rollout_migration/publish.rs b/codex-rs/thread-store/src/local/rollout_migration/publish.rs index cd42249970..29d0390750 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/publish.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/publish.rs @@ -22,8 +22,8 @@ use std::os::unix::fs::OpenOptionsExt; use std::os::unix::fs::PermissionsExt; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use tokio::fs::File; use tokio::io::AsyncBufReadExt; use tokio::io::AsyncWriteExt; diff --git a/codex-rs/thread-store/src/local/rollout_migration/rollback_plan.rs b/codex-rs/thread-store/src/local/rollout_migration/rollback_plan.rs index d28c1c09a2..9f1b253a79 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/rollback_plan.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/rollback_plan.rs @@ -10,11 +10,11 @@ use std::collections::HashMap; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::UserMessageEvent; +use codex_rollout::CompactedItem; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use super::migration_error; use super::rollback; diff --git a/codex-rs/thread-store/src/local/rollout_migration/rollback_replay.rs b/codex-rs/thread-store/src/local/rollout_migration/rollback_replay.rs index 8d0cb30fd9..bdc3d3738c 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/rollback_replay.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/rollback_replay.rs @@ -6,7 +6,7 @@ //! the model. use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; +use codex_rollout::RolloutItem; use super::rollback; diff --git a/codex-rs/thread-store/src/local/rollout_migration/startup_tests.rs b/codex-rs/thread-store/src/local/rollout_migration/startup_tests.rs index e33c2f4133..041dd1df45 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/startup_tests.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/startup_tests.rs @@ -6,14 +6,14 @@ use std::time::Duration; use codex_protocol::ThreadId; use codex_protocol::protocol::EventMsg; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::UserMessageEvent; use codex_rollout::RolloutConfig; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use codex_rollout::RolloutRecorder; use pretty_assertions::assert_eq; use tempfile::TempDir; diff --git a/codex-rs/thread-store/src/local/rollout_migration/subagent.rs b/codex-rs/thread-store/src/local/rollout_migration/subagent.rs index 54cfc75909..775b6f447d 100644 --- a/codex-rs/thread-store/src/local/rollout_migration/subagent.rs +++ b/codex-rs/thread-store/src/local/rollout_migration/subagent.rs @@ -12,11 +12,11 @@ use std::fs::File; use std::path::PathBuf; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionMetaLine; use codex_rollout::ModelContextScan; use codex_rollout::ModelContextScanProgress; use codex_rollout::ReverseJsonlScanner; +use codex_rollout::RolloutItem; use codex_rollout::ScanOutcome; use serde_json::Value; diff --git a/codex-rs/thread-store/src/local/rollout_migration_tests.rs b/codex-rs/thread-store/src/local/rollout_migration_tests.rs index bdad98164f..f1c98f286f 100644 --- a/codex-rs/thread-store/src/local/rollout_migration_tests.rs +++ b/codex-rs/thread-store/src/local/rollout_migration_tests.rs @@ -16,12 +16,9 @@ use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AgentMessageEvent; use codex_protocol::protocol::AskForApproval; -use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::ItemCompletedEvent; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; @@ -33,7 +30,10 @@ use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnContextItem; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; +use codex_rollout::CompactedItem; use codex_rollout::RolloutConfig; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use pretty_assertions::assert_eq; use serde_json::json; use tempfile::TempDir; diff --git a/codex-rs/thread-store/src/local/thread_history/read_tests.rs b/codex-rs/thread-store/src/local/thread_history/read_tests.rs index ea771b68c7..aa5adae78f 100644 --- a/codex-rs/thread-store/src/local/thread_history/read_tests.rs +++ b/codex-rs/thread-store/src/local/thread_history/read_tests.rs @@ -6,12 +6,12 @@ use codex_app_server_protocol::CodexErrorInfo; use codex_protocol::ThreadId; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::HistoryPosition; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use pretty_assertions::assert_eq; use tempfile::TempDir; diff --git a/codex-rs/thread-store/src/local/thread_history_materialization.rs b/codex-rs/thread-store/src/local/thread_history_materialization.rs index 9dced72551..2901d4a9b5 100644 --- a/codex-rs/thread-store/src/local/thread_history_materialization.rs +++ b/codex-rs/thread-store/src/local/thread_history_materialization.rs @@ -5,7 +5,7 @@ use chrono::DateTime; use codex_app_server_protocol::ThreadHistoryChangeSet; use codex_app_server_protocol::project_rollout_line; use codex_protocol::ThreadId; -use codex_protocol::protocol::RolloutLine; +use codex_rollout::RolloutLine; use tokio::io::AsyncReadExt; use tokio::io::AsyncSeekExt; use tracing::warn; diff --git a/codex-rs/thread-store/src/local/thread_history_materialization_tests.rs b/codex-rs/thread-store/src/local/thread_history_materialization_tests.rs index 465d401a74..516c80ecb3 100644 --- a/codex-rs/thread-store/src/local/thread_history_materialization_tests.rs +++ b/codex-rs/thread-store/src/local/thread_history_materialization_tests.rs @@ -19,8 +19,6 @@ use codex_protocol::protocol::HistoryPosition; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::RateLimitSnapshot; use codex_protocol::protocol::RateLimitWindow; -use codex_protocol::protocol::RolloutItem; -use codex_protocol::protocol::RolloutLine; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode; @@ -29,6 +27,8 @@ use codex_protocol::protocol::TurnCompleteEvent; use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; use codex_rollout::RolloutConfig; +use codex_rollout::RolloutItem; +use codex_rollout::RolloutLine; use codex_rollout::RolloutRecorder; use codex_rollout::RolloutRecorderParams; use codex_utils_absolute_path::test_support::PathExt; diff --git a/codex-rs/thread-store/src/local/update_thread_metadata.rs b/codex-rs/thread-store/src/local/update_thread_metadata.rs index 44952e3c7f..b4491f3cd4 100644 --- a/codex-rs/thread-store/src/local/update_thread_metadata.rs +++ b/codex-rs/thread-store/src/local/update_thread_metadata.rs @@ -4,11 +4,11 @@ use std::path::PathBuf; use chrono::Utc; use codex_protocol::ThreadId; use codex_protocol::protocol::GitInfo; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode; use codex_rollout::ARCHIVED_SESSIONS_SUBDIR; +use codex_rollout::RolloutItem; use codex_rollout::append_rollout_item_to_path; use codex_rollout::append_thread_name; use codex_rollout::find_archived_thread_path_by_id_str; diff --git a/codex-rs/thread-store/src/thread_metadata_sync.rs b/codex-rs/thread-store/src/thread_metadata_sync.rs index d320ecb5bc..e5a2d34036 100644 --- a/codex-rs/thread-store/src/thread_metadata_sync.rs +++ b/codex-rs/thread-store/src/thread_metadata_sync.rs @@ -10,12 +10,12 @@ use codex_protocol::ThreadId; use codex_protocol::items::TurnItem; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::GitInfo; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode; use codex_protocol::protocol::UserMessageEvent; use codex_protocol::protocol::strip_user_message_prefix; use codex_protocol::protocol::user_message_preview; +use codex_rollout::RolloutItem; use codex_state::ThreadMetadata; use crate::CreateThreadParams; @@ -412,7 +412,6 @@ mod tests { use codex_protocol::models::PermissionProfile; use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::protocol::AskForApproval; - use codex_protocol::protocol::CompactedItem; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionMetaLine; @@ -425,6 +424,7 @@ mod tests { use codex_protocol::protocol::TurnStartedEvent; use codex_protocol::protocol::UserMessageEvent; use codex_protocol::user_input::UserInput; + use codex_rollout::CompactedItem; use pretty_assertions::assert_eq; use super::*; diff --git a/codex-rs/thread-store/src/types.rs b/codex-rs/thread-store/src/types.rs index d6a54a1146..39a8bc3075 100644 --- a/codex-rs/thread-store/src/types.rs +++ b/codex-rs/thread-store/src/types.rs @@ -15,12 +15,12 @@ use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::GitInfo; use codex_protocol::protocol::HistoryPosition; use codex_protocol::protocol::MultiAgentVersion; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadMemoryMode as MemoryMode; use codex_protocol::protocol::ThreadSource; use codex_protocol::protocol::TokenUsage; +use codex_rollout::RolloutItem; use serde::Deserialize; use serde::Deserializer; use serde::Serialize; diff --git a/codex-rs/tui/Cargo.toml b/codex-rs/tui/Cargo.toml index 8d79afc202..ca037f7b95 100644 --- a/codex-rs/tui/Cargo.toml +++ b/codex-rs/tui/Cargo.toml @@ -35,6 +35,7 @@ codex-cloud-config = { workspace = true } codex-config = { workspace = true } codex-connectors = { workspace = true } codex-core-plugins = { workspace = true } +codex-history = { workspace = true } codex-exec-server = { workspace = true } codex-features = { workspace = true } codex-feedback = { workspace = true } diff --git a/codex-rs/tui/src/app/tests.rs b/codex-rs/tui/src/app/tests.rs index 8507e97cc7..ca0bed69e8 100644 --- a/codex-rs/tui/src/app/tests.rs +++ b/codex-rs/tui/src/app/tests.rs @@ -94,6 +94,7 @@ use codex_app_server_protocol::TurnStatus; use codex_app_server_protocol::UserInput; use codex_app_server_protocol::UserInput as AppServerUserInput; use codex_app_server_protocol::WarningNotification; +use codex_history::RolloutItem; use codex_models_manager::test_support::construct_model_info_offline_for_tests; use codex_models_manager::test_support::get_model_offline_for_tests; use codex_otel::SessionTelemetry; @@ -113,7 +114,6 @@ use codex_protocol::openai_models::MODEL_SPECIALTY_CYBER; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::MAX_THREAD_GOAL_OBJECTIVE_CHARS; use codex_protocol::protocol::MultiAgentVersion; -use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::SessionMeta; use codex_protocol::protocol::SessionSource as RolloutSessionSource; use codex_protocol::protocol::SubAgentSource;