Extract catalog routes from processor
This commit is contained in:
parent
c86de6fa00
commit
72ab5fffcf
5 changed files with 211 additions and 206 deletions
|
|
@ -46,6 +46,7 @@ remembers doctrine; the branch remembers the blade.
|
|||
- One-off command execution and command stream write/resize/terminate route handling now live in `codex_message_processor/command_routes.rs`; `CommandExecManager` remains the lifecycle owner, while the root processor is about 7,800 lines.
|
||||
- Git diff-to-origin, fuzzy file search/session routes, feedback upload, and Windows sandbox setup now live in `codex_message_processor/utility_routes.rs`; the root processor is about 7,397 lines.
|
||||
- Realtime conversation routes now live in `codex_message_processor/realtime_routes.rs`, and review-start orchestration now lives in `codex_message_processor/review_routes.rs`; the root processor is about 6,938 lines.
|
||||
- Model/catalog routes now live in `codex_message_processor/catalog_routes.rs`: model list, collaboration-mode list, experimental feature list, and mock experimental method. The root processor is about 6,738 lines.
|
||||
- The May 2026 foundation migration in `notes/epiphany-ideal-architecture-rebuild-plan.md` is complete enough to defend. Read `notes/epiphany-architectural-teardown.md` before touching Epiphany control-plane code, but do not treat it as an open-ended excuse to keep shaving the altar. The rebuild moved scene projection, freshness derivation, pressure policy, targeted context shards, bounded graph traversal, job/progress view derivation, planning view derivation, reorientation resume/regather verdict policy, pure CRRC recommendation policy, fixed-lane coordinator decision policy, role-board projection policy, role/reorient result interpretation, role self-persistence review policy, and role/reorient acceptance bundle policy into `epiphany-core`; typed acceptance receipts replaced summary-string identity for live accept paths, runtime links are dual-written on launch, and result read-back now prefers runtime links.
|
||||
- Read `notes/epiphany-ideal-architecture-rebuild-plan.md` immediately after the teardown. It defines the smallest coherent replacement architecture: durable `EpiphanyState`, runtime-spine-owned `RuntimeState`, separate role memory/heartbeat state, `epiphany-core` as policy owner, app-server as adapter, Aquarium as reflector, typed acceptance receipts, and derived view lenses instead of a protocol verb zoo.
|
||||
- Do not continue Aquarium UI, bridge, Face, or dogfood expansion until the teardown has a source-grounded cleanup slice plan. Epiphany is the foundation; patches on patches are not a purification rite, they are how the altar becomes load-bearing garbage.
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,5 @@
|
|||
mod auth_routes;
|
||||
mod catalog_routes;
|
||||
mod command_routes;
|
||||
mod epiphany_automation;
|
||||
mod epiphany_mutation_routes;
|
||||
|
|
@ -4250,207 +4251,6 @@ impl CodexMessageProcessor {
|
|||
Ok((items, next_cursor))
|
||||
}
|
||||
|
||||
async fn list_models(
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ModelListParams,
|
||||
) {
|
||||
let ModelListParams {
|
||||
limit,
|
||||
cursor,
|
||||
include_hidden,
|
||||
} = params;
|
||||
let models = supported_models(thread_manager, include_hidden.unwrap_or(false)).await;
|
||||
let total = models.len();
|
||||
|
||||
if total == 0 {
|
||||
let response = ModelListResponse {
|
||||
data: Vec::new(),
|
||||
next_cursor: None,
|
||||
};
|
||||
outgoing.send_response(request_id, response).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let effective_limit = limit.unwrap_or(total as u32).max(1) as usize;
|
||||
let effective_limit = effective_limit.min(total);
|
||||
let start = match cursor {
|
||||
Some(cursor) => match cursor.parse::<usize>() {
|
||||
Ok(idx) => idx,
|
||||
Err(_) => {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!("invalid cursor: {cursor}"),
|
||||
data: None,
|
||||
};
|
||||
outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => 0,
|
||||
};
|
||||
|
||||
if start > total {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!("cursor {start} exceeds total models {total}"),
|
||||
data: None,
|
||||
};
|
||||
outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let end = start.saturating_add(effective_limit).min(total);
|
||||
let items = models[start..end].to_vec();
|
||||
let next_cursor = if end < total {
|
||||
Some(end.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let response = ModelListResponse {
|
||||
data: items,
|
||||
next_cursor,
|
||||
};
|
||||
outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
|
||||
async fn list_collaboration_modes(
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
request_id: ConnectionRequestId,
|
||||
params: CollaborationModeListParams,
|
||||
) {
|
||||
let CollaborationModeListParams {} = params;
|
||||
let items = thread_manager
|
||||
.list_collaboration_modes()
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
let response = CollaborationModeListResponse { data: items };
|
||||
outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
|
||||
async fn experimental_feature_list(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ExperimentalFeatureListParams,
|
||||
) {
|
||||
let ExperimentalFeatureListParams { cursor, limit } = params;
|
||||
let config = match self.load_latest_config(/*fallback_cwd*/ None).await {
|
||||
Ok(config) => config,
|
||||
Err(error) => {
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let data = FEATURES
|
||||
.iter()
|
||||
.map(|spec| {
|
||||
let (stage, display_name, description, announcement) = match spec.stage {
|
||||
Stage::Experimental {
|
||||
name,
|
||||
menu_description,
|
||||
announcement,
|
||||
} => (
|
||||
ApiExperimentalFeatureStage::Beta,
|
||||
Some(name.to_string()),
|
||||
Some(menu_description.to_string()),
|
||||
Some(announcement.to_string()),
|
||||
),
|
||||
Stage::UnderDevelopment => (
|
||||
ApiExperimentalFeatureStage::UnderDevelopment,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
Stage::Stable => (ApiExperimentalFeatureStage::Stable, None, None, None),
|
||||
Stage::Deprecated => {
|
||||
(ApiExperimentalFeatureStage::Deprecated, None, None, None)
|
||||
}
|
||||
Stage::Removed => (ApiExperimentalFeatureStage::Removed, None, None, None),
|
||||
};
|
||||
|
||||
ApiExperimentalFeature {
|
||||
name: spec.key.to_string(),
|
||||
stage,
|
||||
display_name,
|
||||
description,
|
||||
announcement,
|
||||
enabled: config.features.enabled(spec.id),
|
||||
default_enabled: spec.default_enabled,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let total = data.len();
|
||||
if total == 0 {
|
||||
self.outgoing
|
||||
.send_response(
|
||||
request_id,
|
||||
ExperimentalFeatureListResponse {
|
||||
data: Vec::new(),
|
||||
next_cursor: None,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clamp to 1 so limit=0 cannot return a non-advancing page.
|
||||
let effective_limit = limit.unwrap_or(total as u32).max(1) as usize;
|
||||
let effective_limit = effective_limit.min(total);
|
||||
let start = match cursor {
|
||||
Some(cursor) => match cursor.parse::<usize>() {
|
||||
Ok(idx) => idx,
|
||||
Err(_) => {
|
||||
self.send_invalid_request_error(
|
||||
request_id,
|
||||
format!("invalid cursor: {cursor}"),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => 0,
|
||||
};
|
||||
|
||||
if start > total {
|
||||
self.send_invalid_request_error(
|
||||
request_id,
|
||||
format!("cursor {start} exceeds total feature flags {total}"),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
let end = start.saturating_add(effective_limit).min(total);
|
||||
let data = data[start..end].to_vec();
|
||||
let next_cursor = if end < total {
|
||||
Some(end.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.outgoing
|
||||
.send_response(
|
||||
request_id,
|
||||
ExperimentalFeatureListResponse { data, next_cursor },
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn mock_experimental_method(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: MockExperimentalMethodParams,
|
||||
) {
|
||||
let MockExperimentalMethodParams { value } = params;
|
||||
let response = MockExperimentalMethodResponse { echoed: value };
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
|
||||
async fn send_invalid_request_error(&self, request_id: ConnectionRequestId, message: String) {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
|
|
|
|||
204
vendor/codex/codex-rs/app-server/src/codex_message_processor/catalog_routes.rs
vendored
Normal file
204
vendor/codex/codex-rs/app-server/src/codex_message_processor/catalog_routes.rs
vendored
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
use super::*;
|
||||
|
||||
impl CodexMessageProcessor {
|
||||
pub(super) async fn list_models(
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ModelListParams,
|
||||
) {
|
||||
let ModelListParams {
|
||||
limit,
|
||||
cursor,
|
||||
include_hidden,
|
||||
} = params;
|
||||
let models = supported_models(thread_manager, include_hidden.unwrap_or(false)).await;
|
||||
let total = models.len();
|
||||
|
||||
if total == 0 {
|
||||
let response = ModelListResponse {
|
||||
data: Vec::new(),
|
||||
next_cursor: None,
|
||||
};
|
||||
outgoing.send_response(request_id, response).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let effective_limit = limit.unwrap_or(total as u32).max(1) as usize;
|
||||
let effective_limit = effective_limit.min(total);
|
||||
let start = match cursor {
|
||||
Some(cursor) => match cursor.parse::<usize>() {
|
||||
Ok(idx) => idx,
|
||||
Err(_) => {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!("invalid cursor: {cursor}"),
|
||||
data: None,
|
||||
};
|
||||
outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => 0,
|
||||
};
|
||||
|
||||
if start > total {
|
||||
let error = JSONRPCErrorError {
|
||||
code: INVALID_REQUEST_ERROR_CODE,
|
||||
message: format!("cursor {start} exceeds total models {total}"),
|
||||
data: None,
|
||||
};
|
||||
outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
|
||||
let end = start.saturating_add(effective_limit).min(total);
|
||||
let items = models[start..end].to_vec();
|
||||
let next_cursor = if end < total {
|
||||
Some(end.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let response = ModelListResponse {
|
||||
data: items,
|
||||
next_cursor,
|
||||
};
|
||||
outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
|
||||
pub(super) async fn list_collaboration_modes(
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
request_id: ConnectionRequestId,
|
||||
params: CollaborationModeListParams,
|
||||
) {
|
||||
let CollaborationModeListParams {} = params;
|
||||
let items = thread_manager
|
||||
.list_collaboration_modes()
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
let response = CollaborationModeListResponse { data: items };
|
||||
outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
|
||||
pub(super) async fn experimental_feature_list(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ExperimentalFeatureListParams,
|
||||
) {
|
||||
let ExperimentalFeatureListParams { cursor, limit } = params;
|
||||
let config = match self.load_latest_config(/*fallback_cwd*/ None).await {
|
||||
Ok(config) => config,
|
||||
Err(error) => {
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let data = FEATURES
|
||||
.iter()
|
||||
.map(|spec| {
|
||||
let (stage, display_name, description, announcement) = match spec.stage {
|
||||
Stage::Experimental {
|
||||
name,
|
||||
menu_description,
|
||||
announcement,
|
||||
} => (
|
||||
ApiExperimentalFeatureStage::Beta,
|
||||
Some(name.to_string()),
|
||||
Some(menu_description.to_string()),
|
||||
Some(announcement.to_string()),
|
||||
),
|
||||
Stage::UnderDevelopment => (
|
||||
ApiExperimentalFeatureStage::UnderDevelopment,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
),
|
||||
Stage::Stable => (ApiExperimentalFeatureStage::Stable, None, None, None),
|
||||
Stage::Deprecated => {
|
||||
(ApiExperimentalFeatureStage::Deprecated, None, None, None)
|
||||
}
|
||||
Stage::Removed => (ApiExperimentalFeatureStage::Removed, None, None, None),
|
||||
};
|
||||
|
||||
ApiExperimentalFeature {
|
||||
name: spec.key.to_string(),
|
||||
stage,
|
||||
display_name,
|
||||
description,
|
||||
announcement,
|
||||
enabled: config.features.enabled(spec.id),
|
||||
default_enabled: spec.default_enabled,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let total = data.len();
|
||||
if total == 0 {
|
||||
self.outgoing
|
||||
.send_response(
|
||||
request_id,
|
||||
ExperimentalFeatureListResponse {
|
||||
data: Vec::new(),
|
||||
next_cursor: None,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clamp to 1 so limit=0 cannot return a non-advancing page.
|
||||
let effective_limit = limit.unwrap_or(total as u32).max(1) as usize;
|
||||
let effective_limit = effective_limit.min(total);
|
||||
let start = match cursor {
|
||||
Some(cursor) => match cursor.parse::<usize>() {
|
||||
Ok(idx) => idx,
|
||||
Err(_) => {
|
||||
self.send_invalid_request_error(
|
||||
request_id,
|
||||
format!("invalid cursor: {cursor}"),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => 0,
|
||||
};
|
||||
|
||||
if start > total {
|
||||
self.send_invalid_request_error(
|
||||
request_id,
|
||||
format!("cursor {start} exceeds total feature flags {total}"),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
let end = start.saturating_add(effective_limit).min(total);
|
||||
let data = data[start..end].to_vec();
|
||||
let next_cursor = if end < total {
|
||||
Some(end.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.outgoing
|
||||
.send_response(
|
||||
request_id,
|
||||
ExperimentalFeatureListResponse { data, next_cursor },
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(super) async fn mock_experimental_method(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: MockExperimentalMethodParams,
|
||||
) {
|
||||
let MockExperimentalMethodParams { value } = params;
|
||||
let response = MockExperimentalMethodResponse { echoed: value };
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
}
|
||||
Reference in a new issue