Move retrieve route ownership into bridge

This commit is contained in:
Meta Vens 2026-06-09 05:42:24 +01:00
commit d890ab8bca
6 changed files with 69 additions and 37 deletions

View file

@ -9,6 +9,33 @@ use epiphany_core::EpiphanyRetrieveResponse as CoreEpiphanyRetrieveResponse;
use epiphany_core::EpiphanyRetrieveResult as CoreEpiphanyRetrieveResult;
use epiphany_core::EpiphanyRetrieveResultKind as CoreEpiphanyRetrieveResultKind;
use epiphany_state_model::EpiphanyRetrievalState;
use std::path::PathBuf;
use crate::error::EpiphanyBridgeError;
use crate::error::Result as BridgeResult;
use crate::retrieve::normalize_thread_epiphany_retrieve_query;
use crate::retrieve::retrieve_epiphany_for_paths;
pub async fn retrieve_thread_epiphany_for_paths(
workspace_root: PathBuf,
codex_home: PathBuf,
query: String,
limit: Option<u32>,
path_prefixes: Vec<PathBuf>,
) -> BridgeResult<ThreadEpiphanyRetrieveResponse> {
let query = normalize_thread_epiphany_retrieve_query(query, limit, path_prefixes)
.map_err(EpiphanyBridgeError::InvalidRequest)?;
let response = retrieve_epiphany_for_paths(workspace_root, codex_home, query)
.await
.map_err(|err| {
EpiphanyBridgeError::Fatal(format!("failed to retrieve Epiphany results: {err}"))
})?;
protocol_retrieve_response(response).map_err(|err| {
EpiphanyBridgeError::Fatal(format!(
"failed to project Epiphany retrieve response: {err}"
))
})
}
pub fn protocol_retrieve_response(
response: CoreEpiphanyRetrieveResponse,

View file

@ -464,14 +464,12 @@ Code refs:
The app-server handler:
1. parses the thread id.
2. trims and rejects empty queries.
3. rejects zero limits.
4. requires the thread to be loaded.
5. clamps limit to Epiphany bounds.
6. calls `epiphany-codex-bridge::retrieve_thread_epiphany`.
7. maps core results into app-server protocol DTOs.
2. requires the thread to be loaded.
3. reads the loaded thread config and Codex home as host facts.
4. calls `epiphany-codex-bridge::retrieve_protocol::retrieve_thread_epiphany_for_paths`.
5. maps bridge errors to JSON-RPC invalid-request or internal-error responses.
`retrieve_thread_epiphany` snapshots the host config, extracts `cwd` as workspace root, gets Codex home from the host seam, and runs `epiphany_core::retrieve_workspace` in `spawn_blocking`.
`retrieve_thread_epiphany_for_paths` owns raw request normalization, including query trimming, empty-query rejection, zero-limit rejection, limit clamping, and path-prefix handling. It then runs `epiphany_core::retrieve_workspace` through the bridge retrieval worker and projects typed core results into the legacy Codex JSON-RPC retrieve response.
`epiphany-core::retrieve_workspace`:

View file

@ -842,6 +842,13 @@ app-server still checks that the target thread is loaded and maps errors onto
JSON-RPC responses, but it no longer shapes those patches itself.
`epiphany_read_routes.rs` is about 579 lines after this cut.
The retrieve read route has now lost its local normalization/projection opinion
too. `epiphany-codex-bridge::retrieve_protocol::retrieve_thread_epiphany_for_paths`
owns raw query normalization, core retrieval invocation, and Codex JSON-RPC
retrieve response projection. App-server keeps thread-id parsing, loaded-thread
lookup, config/Codex-home fact supply, response emission, and bridge-error to
JSON-RPC mapping.
Also: MCP itself is allowed to be JSON. The target is not "replace MCP JSON";
the target is an Epiphany-owned boundary that speaks typed Epiphany
intent/result/receipt documents internally and normal MCP JSON-RPC externally.

Binary file not shown.

View file

@ -472,8 +472,10 @@ current_status:
`ThreadEpiphanyScene` plus scene-action DTOs for view responses.
Retrieval follows the boundary too: `retrieve.rs` executes normalization,
indexing, state lookup, and typed retrieval responses; `retrieve_protocol.rs`
owns Codex JSON-RPC retrieve/index response projection and absolute-path DTO
validation.
owns Codex JSON-RPC retrieve/index response projection, absolute-path DTO
validation, and the route-facing retrieve service that normalizes raw
request fields before invoking core retrieval. App-server supplies loaded
thread cwd/Codex-home facts and maps bridge errors to JSON-RPC responses.
View response assembly no longer owns private lens/source/reorient-status
projection helpers; those small enum conversions route through
`protocol_edge`, and the Codex response assembler is now named

View file

@ -3,6 +3,7 @@ use codex_core::CodexThread;
use codex_protocol::ThreadId;
use codex_protocol::protocol::EpiphanyRetrievalState;
use epiphany_codex_bridge::cultnet::EpiphanySurfaceSource;
use epiphany_codex_bridge::error::EpiphanyBridgeError;
use epiphany_codex_bridge::invalidation::epiphany_freshness_watcher_snapshot;
use epiphany_codex_bridge::launch::EPIPHANY_REORIENT_LAUNCH_BINDING_ID;
use epiphany_codex_bridge::launch::epiphany_role_binding_id;
@ -18,9 +19,7 @@ use epiphany_codex_bridge::protocol_edge::protocol_graph_query_to_core;
use epiphany_codex_bridge::protocol_edge::protocol_role_id_to_core;
use epiphany_codex_bridge::protocol_edge::protocol_view_lenses_to_core;
use epiphany_codex_bridge::retrieve::epiphany_retrieval_state_for_paths;
use epiphany_codex_bridge::retrieve::normalize_thread_epiphany_retrieve_query;
use epiphany_codex_bridge::retrieve::retrieve_epiphany_for_paths;
use epiphany_codex_bridge::retrieve_protocol::protocol_retrieve_response;
use epiphany_codex_bridge::retrieve_protocol::retrieve_thread_epiphany_for_paths;
use epiphany_codex_bridge::view_protocol::EpiphanyFreshnessResponseInput;
use epiphany_codex_bridge::view_protocol::EpiphanyReorientResultResponseInput;
use epiphany_codex_bridge::view_protocol::EpiphanyRoleResultResponseInput;
@ -434,15 +433,6 @@ impl CodexMessageProcessor {
}
};
let query = match normalize_thread_epiphany_retrieve_query(query, limit, path_prefixes) {
Ok(query) => query,
Err(message) => {
self.send_invalid_request_error(request_id, message.to_string())
.await;
return;
}
};
let thread = match self.thread_manager.get_thread(thread_uuid).await {
Ok(thread) => thread,
Err(_) => {
@ -457,21 +447,29 @@ impl CodexMessageProcessor {
let config = thread.config_snapshot().await;
let codex_home = thread.codex_home().await;
let response =
match retrieve_epiphany_for_paths(config.cwd.to_path_buf(), codex_home, query)
.await
.and_then(protocol_retrieve_response)
{
Ok(response) => response,
Err(err) => {
self.send_internal_error(
request_id,
format!("failed to retrieve Epiphany results for {thread_uuid}: {err}"),
)
.await;
return;
}
};
let response = match retrieve_thread_epiphany_for_paths(
config.cwd.to_path_buf(),
codex_home,
query,
limit,
path_prefixes,
)
.await
{
Ok(response) => response,
Err(EpiphanyBridgeError::InvalidRequest(message)) => {
self.send_invalid_request_error(request_id, message).await;
return;
}
Err(err) => {
self.send_internal_error(
request_id,
format!("failed to retrieve Epiphany results for {thread_uuid}: {err}"),
)
.await;
return;
}
};
self.outgoing.send_response(request_id, response).await;
}