Move response projection out of app server
This commit is contained in:
parent
7385d28266
commit
4dcfa90c21
6 changed files with 281 additions and 252 deletions
|
|
@ -1,9 +1,42 @@
|
|||
use crate::cultnet::EpiphanyFreshnessSurface;
|
||||
use crate::cultnet::EpiphanyGraphFreshnessStatus;
|
||||
use crate::cultnet::EpiphanyInvalidationStatus;
|
||||
use crate::cultnet::EpiphanyJobKind;
|
||||
use crate::cultnet::EpiphanyJobStatus;
|
||||
use crate::cultnet::EpiphanyJobView;
|
||||
use crate::cultnet::EpiphanyReorientAction;
|
||||
use crate::cultnet::EpiphanyReorientCheckpointStatus;
|
||||
use crate::cultnet::EpiphanyReorientDecision;
|
||||
use crate::cultnet::EpiphanyReorientFreshnessStatus;
|
||||
use crate::cultnet::EpiphanyReorientPressureLevel;
|
||||
use crate::cultnet::EpiphanyReorientReason;
|
||||
use crate::cultnet::EpiphanyReorientStateStatus;
|
||||
use crate::cultnet::EpiphanyRetrievalFreshnessStatus;
|
||||
use crate::cultnet::EpiphanySurfaceSource;
|
||||
use codex_app_server_protocol::ThreadEpiphanyContextParams;
|
||||
use codex_app_server_protocol::ThreadEpiphanyDistillParams;
|
||||
use codex_app_server_protocol::ThreadEpiphanyFreshnessResponse;
|
||||
use codex_app_server_protocol::ThreadEpiphanyFreshnessSource;
|
||||
use codex_app_server_protocol::ThreadEpiphanyGraphFreshness;
|
||||
use codex_app_server_protocol::ThreadEpiphanyGraphFreshnessStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyGraphQuery;
|
||||
use codex_app_server_protocol::ThreadEpiphanyGraphQueryDirection;
|
||||
use codex_app_server_protocol::ThreadEpiphanyGraphQueryKind;
|
||||
use codex_app_server_protocol::ThreadEpiphanyInvalidationInput;
|
||||
use codex_app_server_protocol::ThreadEpiphanyInvalidationStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyJob;
|
||||
use codex_app_server_protocol::ThreadEpiphanyJobKind;
|
||||
use codex_app_server_protocol::ThreadEpiphanyJobStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyPressureLevel;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientAction;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientCheckpointStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientDecision;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientReason;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientSource;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientStateStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyReorientWorkerLaunchDocument;
|
||||
use codex_app_server_protocol::ThreadEpiphanyRetrievalFreshness;
|
||||
use codex_app_server_protocol::ThreadEpiphanyRetrievalFreshnessStatus;
|
||||
use codex_app_server_protocol::ThreadEpiphanyRoleWorkerLaunchDocument;
|
||||
use codex_app_server_protocol::ThreadEpiphanyUpdatePatch;
|
||||
use codex_app_server_protocol::ThreadEpiphanyViewLens;
|
||||
|
|
@ -136,6 +169,175 @@ pub fn protocol_update_patch_to_core(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn protocol_freshness_response_from_surface(
|
||||
surface: EpiphanyFreshnessSurface,
|
||||
) -> ThreadEpiphanyFreshnessResponse {
|
||||
ThreadEpiphanyFreshnessResponse {
|
||||
thread_id: surface.thread_id,
|
||||
source: match surface.source {
|
||||
EpiphanySurfaceSource::Stored => ThreadEpiphanyFreshnessSource::Stored,
|
||||
EpiphanySurfaceSource::Live => ThreadEpiphanyFreshnessSource::Live,
|
||||
},
|
||||
state_revision: surface.state_revision,
|
||||
retrieval: ThreadEpiphanyRetrievalFreshness {
|
||||
status: match surface.retrieval.status {
|
||||
EpiphanyRetrievalFreshnessStatus::Missing => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Missing
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Ready => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Ready
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Stale => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Stale
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Indexing => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Indexing
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Unavailable => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Unavailable
|
||||
}
|
||||
},
|
||||
semantic_available: surface.retrieval.semantic_available,
|
||||
last_indexed_at_unix_seconds: surface.retrieval.last_indexed_at_unix_seconds,
|
||||
indexed_file_count: surface.retrieval.indexed_file_count,
|
||||
indexed_chunk_count: surface.retrieval.indexed_chunk_count,
|
||||
dirty_paths: surface.retrieval.dirty_paths,
|
||||
note: surface.retrieval.note,
|
||||
},
|
||||
graph: ThreadEpiphanyGraphFreshness {
|
||||
status: match surface.graph.status {
|
||||
EpiphanyGraphFreshnessStatus::Missing => {
|
||||
ThreadEpiphanyGraphFreshnessStatus::Missing
|
||||
}
|
||||
EpiphanyGraphFreshnessStatus::Ready => ThreadEpiphanyGraphFreshnessStatus::Ready,
|
||||
EpiphanyGraphFreshnessStatus::Stale => ThreadEpiphanyGraphFreshnessStatus::Stale,
|
||||
},
|
||||
graph_freshness: surface.graph.graph_freshness,
|
||||
checkpoint_id: surface.graph.checkpoint_id,
|
||||
dirty_path_count: surface.graph.dirty_path_count,
|
||||
dirty_paths: surface.graph.dirty_paths,
|
||||
open_question_count: surface.graph.open_question_count,
|
||||
open_gap_count: surface.graph.open_gap_count,
|
||||
note: surface.graph.note,
|
||||
},
|
||||
watcher: ThreadEpiphanyInvalidationInput {
|
||||
status: match surface.watcher.status {
|
||||
EpiphanyInvalidationStatus::Unavailable => {
|
||||
ThreadEpiphanyInvalidationStatus::Unavailable
|
||||
}
|
||||
EpiphanyInvalidationStatus::Clean => ThreadEpiphanyInvalidationStatus::Clean,
|
||||
EpiphanyInvalidationStatus::Changed => ThreadEpiphanyInvalidationStatus::Changed,
|
||||
},
|
||||
watched_root: surface.watcher.watched_root,
|
||||
observed_at_unix_seconds: surface.watcher.observed_at_unix_seconds,
|
||||
changed_path_count: surface.watcher.changed_path_count,
|
||||
changed_paths: surface.watcher.changed_paths,
|
||||
graph_node_ids: surface.watcher.graph_node_ids,
|
||||
active_frontier_node_ids: surface.watcher.active_frontier_node_ids,
|
||||
note: surface.watcher.note,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn protocol_job_from_surface(
|
||||
job: EpiphanyJobView,
|
||||
launcher_job_id: Option<String>,
|
||||
backend_job_id_override: Option<String>,
|
||||
) -> ThreadEpiphanyJob {
|
||||
ThreadEpiphanyJob {
|
||||
id: job.id,
|
||||
kind: match job.kind {
|
||||
EpiphanyJobKind::Indexing => ThreadEpiphanyJobKind::Indexing,
|
||||
EpiphanyJobKind::Remap => ThreadEpiphanyJobKind::Remap,
|
||||
EpiphanyJobKind::Verification => ThreadEpiphanyJobKind::Verification,
|
||||
EpiphanyJobKind::Specialist => ThreadEpiphanyJobKind::Specialist,
|
||||
},
|
||||
scope: job.scope,
|
||||
owner_role: job.owner_role,
|
||||
launcher_job_id,
|
||||
authority_scope: job.authority_scope,
|
||||
backend_job_id: backend_job_id_override.or(job.runtime_job_id),
|
||||
status: match job.status {
|
||||
EpiphanyJobStatus::Idle => ThreadEpiphanyJobStatus::Idle,
|
||||
EpiphanyJobStatus::Needed => ThreadEpiphanyJobStatus::Needed,
|
||||
EpiphanyJobStatus::Pending => ThreadEpiphanyJobStatus::Pending,
|
||||
EpiphanyJobStatus::Running => ThreadEpiphanyJobStatus::Running,
|
||||
EpiphanyJobStatus::Completed => ThreadEpiphanyJobStatus::Completed,
|
||||
EpiphanyJobStatus::Failed => ThreadEpiphanyJobStatus::Failed,
|
||||
EpiphanyJobStatus::Cancelled => ThreadEpiphanyJobStatus::Cancelled,
|
||||
EpiphanyJobStatus::Blocked => ThreadEpiphanyJobStatus::Blocked,
|
||||
EpiphanyJobStatus::Unavailable => ThreadEpiphanyJobStatus::Unavailable,
|
||||
},
|
||||
items_processed: job.items_processed,
|
||||
items_total: job.items_total,
|
||||
progress_note: job.progress_note,
|
||||
last_checkpoint_at_unix_seconds: job.last_checkpoint_at_unix_seconds,
|
||||
blocking_reason: job.blocking_reason,
|
||||
active_thread_ids: job.active_thread_ids,
|
||||
linked_subgoal_ids: job.linked_subgoal_ids,
|
||||
linked_graph_node_ids: job.linked_graph_node_ids,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn protocol_reorient_state_status(
|
||||
status: EpiphanyReorientStateStatus,
|
||||
) -> ThreadEpiphanyReorientStateStatus {
|
||||
match status {
|
||||
EpiphanyReorientStateStatus::Missing => ThreadEpiphanyReorientStateStatus::Missing,
|
||||
EpiphanyReorientStateStatus::Ready => ThreadEpiphanyReorientStateStatus::Ready,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn protocol_reorient_source(source: EpiphanySurfaceSource) -> ThreadEpiphanyReorientSource {
|
||||
match source {
|
||||
EpiphanySurfaceSource::Stored => ThreadEpiphanyReorientSource::Stored,
|
||||
EpiphanySurfaceSource::Live => ThreadEpiphanyReorientSource::Live,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn protocol_reorient_decision(
|
||||
decision: EpiphanyReorientDecision,
|
||||
) -> ThreadEpiphanyReorientDecision {
|
||||
ThreadEpiphanyReorientDecision {
|
||||
action: match decision.action {
|
||||
EpiphanyReorientAction::Resume => ThreadEpiphanyReorientAction::Resume,
|
||||
EpiphanyReorientAction::Regather => ThreadEpiphanyReorientAction::Regather,
|
||||
},
|
||||
checkpoint_status: match decision.checkpoint_status {
|
||||
EpiphanyReorientCheckpointStatus::Missing => {
|
||||
ThreadEpiphanyReorientCheckpointStatus::Missing
|
||||
}
|
||||
EpiphanyReorientCheckpointStatus::ResumeReady => {
|
||||
ThreadEpiphanyReorientCheckpointStatus::ResumeReady
|
||||
}
|
||||
EpiphanyReorientCheckpointStatus::RegatherRequired => {
|
||||
ThreadEpiphanyReorientCheckpointStatus::RegatherRequired
|
||||
}
|
||||
},
|
||||
checkpoint_id: decision.checkpoint_id,
|
||||
pressure_level: match decision.pressure_level {
|
||||
EpiphanyReorientPressureLevel::Unknown => ThreadEpiphanyPressureLevel::Unknown,
|
||||
EpiphanyReorientPressureLevel::Low => ThreadEpiphanyPressureLevel::Low,
|
||||
EpiphanyReorientPressureLevel::Medium => ThreadEpiphanyPressureLevel::Elevated,
|
||||
EpiphanyReorientPressureLevel::High => ThreadEpiphanyPressureLevel::High,
|
||||
EpiphanyReorientPressureLevel::Critical => ThreadEpiphanyPressureLevel::Critical,
|
||||
},
|
||||
retrieval_status: protocol_reorient_retrieval_status(decision.retrieval_status),
|
||||
graph_status: protocol_reorient_graph_status(decision.graph_status),
|
||||
watcher_status: protocol_reorient_watcher_status(decision.watcher_status),
|
||||
reasons: decision
|
||||
.reasons
|
||||
.into_iter()
|
||||
.map(protocol_reorient_reason)
|
||||
.collect(),
|
||||
checkpoint_dirty_paths: decision.checkpoint_dirty_paths,
|
||||
checkpoint_changed_paths: decision.checkpoint_changed_paths,
|
||||
active_frontier_node_ids: decision.active_frontier_node_ids,
|
||||
next_action: decision.next_action,
|
||||
note: decision.note,
|
||||
}
|
||||
}
|
||||
|
||||
fn protocol_view_lens_to_core(lens: ThreadEpiphanyViewLens) -> EpiphanyViewLens {
|
||||
match lens {
|
||||
ThreadEpiphanyViewLens::Scene => EpiphanyViewLens::Scene,
|
||||
|
|
@ -226,3 +428,63 @@ fn protocol_reorient_worker_launch_document_to_core(
|
|||
linked_graph_node_ids: document.linked_graph_node_ids,
|
||||
}
|
||||
}
|
||||
|
||||
fn protocol_reorient_retrieval_status(
|
||||
status: EpiphanyReorientFreshnessStatus,
|
||||
) -> ThreadEpiphanyRetrievalFreshnessStatus {
|
||||
match status {
|
||||
EpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyRetrievalFreshnessStatus::Missing,
|
||||
EpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyRetrievalFreshnessStatus::Ready,
|
||||
EpiphanyReorientFreshnessStatus::Dirty => ThreadEpiphanyRetrievalFreshnessStatus::Indexing,
|
||||
EpiphanyReorientFreshnessStatus::Stale | EpiphanyReorientFreshnessStatus::Changed => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Stale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn protocol_reorient_graph_status(
|
||||
status: EpiphanyReorientFreshnessStatus,
|
||||
) -> ThreadEpiphanyGraphFreshnessStatus {
|
||||
match status {
|
||||
EpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyGraphFreshnessStatus::Missing,
|
||||
EpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyGraphFreshnessStatus::Ready,
|
||||
EpiphanyReorientFreshnessStatus::Dirty
|
||||
| EpiphanyReorientFreshnessStatus::Stale
|
||||
| EpiphanyReorientFreshnessStatus::Changed => ThreadEpiphanyGraphFreshnessStatus::Stale,
|
||||
}
|
||||
}
|
||||
|
||||
fn protocol_reorient_watcher_status(
|
||||
status: EpiphanyReorientFreshnessStatus,
|
||||
) -> ThreadEpiphanyInvalidationStatus {
|
||||
match status {
|
||||
EpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyInvalidationStatus::Unavailable,
|
||||
EpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyInvalidationStatus::Clean,
|
||||
EpiphanyReorientFreshnessStatus::Dirty
|
||||
| EpiphanyReorientFreshnessStatus::Stale
|
||||
| EpiphanyReorientFreshnessStatus::Changed => ThreadEpiphanyInvalidationStatus::Changed,
|
||||
}
|
||||
}
|
||||
|
||||
fn protocol_reorient_reason(reason: EpiphanyReorientReason) -> ThreadEpiphanyReorientReason {
|
||||
match reason {
|
||||
EpiphanyReorientReason::MissingState => ThreadEpiphanyReorientReason::MissingState,
|
||||
EpiphanyReorientReason::MissingCheckpoint => {
|
||||
ThreadEpiphanyReorientReason::MissingCheckpoint
|
||||
}
|
||||
EpiphanyReorientReason::CheckpointReady => ThreadEpiphanyReorientReason::CheckpointReady,
|
||||
EpiphanyReorientReason::CheckpointRequestedRegather => {
|
||||
ThreadEpiphanyReorientReason::CheckpointRequestedRegather
|
||||
}
|
||||
EpiphanyReorientReason::CheckpointPathsDirty => {
|
||||
ThreadEpiphanyReorientReason::CheckpointPathsDirty
|
||||
}
|
||||
EpiphanyReorientReason::CheckpointPathsChanged => {
|
||||
ThreadEpiphanyReorientReason::CheckpointPathsChanged
|
||||
}
|
||||
EpiphanyReorientReason::FrontierChanged => ThreadEpiphanyReorientReason::FrontierChanged,
|
||||
EpiphanyReorientReason::UnanchoredCheckpointWhileStateStale => {
|
||||
ThreadEpiphanyReorientReason::UnanchoredCheckpointWhileStateStale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ remembers doctrine; the branch remembers the blade.
|
|||
- View lens selector semantics are core-owned now. `EpiphanyViewLens`, default view lenses, and lens dependency planning live in `epiphany-core`; `epiphany-codex-bridge::protocol_edge` converts Codex JSON-RPC lens params to core selectors and exposes the core dependency plan so app-server only decides which host facts to load.
|
||||
- Correction: app-server must not own Epiphany request mapping. Codex JSON-RPC request DTO conversion now lives in `epiphany-codex-bridge::protocol_edge`; vendored app-server calls those edge adapters and no longer depends directly on `epiphany-core`.
|
||||
- Context, graph-query, distill, generic job-launch document, and generic update/promote patch request cargo now enters bridge as core `EpiphanyContextParams`, `EpiphanyGraphQuery`, `EpiphanyDistillInput`, `EpiphanyWorkerLaunchDocument`, and `EpiphanyRoleStatePatchDocument`.
|
||||
- Freshness/job/reorient response projection also belongs to the bridge edge now. Vendored app-server no longer keeps local helpers for `EpiphanyFreshnessSurface`, `EpiphanyJobView`, `EpiphanySurfaceSource`, or reorient decision/status enum projection; it gathers host facts, invokes bridge/core services, and sends the Codex JSON-RPC response.
|
||||
- MCP remains JSON because MCP is a JSON protocol. The latest processor cut only moved MCP refresh/OAuth/status/resource/tool-call route handling into `codex_message_processor/mcp_routes.rs`, reducing the root processor to about 8,977 lines; it did not claim MCP payloads are CultNet or make MCP an Epiphany-owned runtime contract.
|
||||
- Codex account auth route handling remains in vendored Codex but now lives in `codex_message_processor/auth_routes.rs`: API-key login, ChatGPT browser/device-code/external-token login, logout, auth status, account, rate limits, and add-credits nudge handling. This preserves Codex ownership of subscription auth while cutting the root processor to about 8,094 lines.
|
||||
- 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.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -393,6 +393,11 @@ current_status:
|
|||
(`EpiphanyReorientLaunchRequestInput` -> `EpiphanyJobLaunchRequest`);
|
||||
bridge supplies only the prompt instruction and retained compatibility
|
||||
binding/owner constants before performing host side effects.
|
||||
Freshness/job/reorient response projection moved out of vendored app-server
|
||||
into `epiphany-codex-bridge::protocol_edge`: app-server gathers host facts,
|
||||
invokes Epiphany bridge services, and sends Codex JSON-RPC responses, while
|
||||
the bridge owns the enum/DTO conversion from typed Epiphany surfaces into
|
||||
`ThreadEpiphany*` edge payloads.
|
||||
The bridge still depends on vendored Codex for app-server protocol DTOs and
|
||||
absolute path validation, so the purification is not done.
|
||||
next_action: Continue Codex starvation and CultNet liberation by cutting bridge-internal response/projection authority. Prioritize the next coordinator/view seam that still composes policy-shaped facts instead of merely loading host facts and projecting core surfaces; keep MCP/OpenAI JSON only at their true protocol/text edges. Do not add compatibility adapters unless they protect a named ownership invariant.
|
||||
|
|
|
|||
|
|
@ -3,18 +3,7 @@ use codex_core::CodexThread;
|
|||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::protocol::EpiphanyRetrievalState;
|
||||
use codex_protocol::protocol::EpiphanyThreadState;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyJobKind;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyJobStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyJobView;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientAction;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientCheckpointStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientDecision;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientFreshnessStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientPressureLevel;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientReason;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyReorientStateStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyStateUpdatedField;
|
||||
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;
|
||||
|
|
@ -32,6 +21,10 @@ use epiphany_codex_bridge::mutation_service::interrupt_thread_epiphany_job;
|
|||
use epiphany_codex_bridge::mutation_service::launch_thread_epiphany_job;
|
||||
use epiphany_codex_bridge::mutation_service::launch_thread_epiphany_reorient;
|
||||
use epiphany_codex_bridge::mutation_service::launch_thread_epiphany_role;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_job_from_surface;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_reorient_decision;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_reorient_source;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_reorient_state_status;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_update_patch_to_core;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_worker_launch_document_to_core;
|
||||
use epiphany_codex_bridge::results::map_core_role_result_role_id;
|
||||
|
|
@ -155,7 +148,7 @@ impl CodexMessageProcessor {
|
|||
revision: applied.revision,
|
||||
changed_fields: protocol_changed_fields,
|
||||
epiphany_state: epiphany_state.clone(),
|
||||
job: thread_epiphany_job_from_surface(
|
||||
job: protocol_job_from_surface(
|
||||
applied.job,
|
||||
Some(applied.launcher_job_id),
|
||||
Some(applied.backend_job_id),
|
||||
|
|
@ -329,14 +322,14 @@ impl CodexMessageProcessor {
|
|||
request_id,
|
||||
ThreadEpiphanyReorientLaunchResponse {
|
||||
thread_id: thread_uuid.to_string(),
|
||||
source: thread_epiphany_reorient_source(applied.source),
|
||||
state_status: thread_epiphany_reorient_state_status(applied.state_status),
|
||||
source: protocol_reorient_source(applied.source),
|
||||
state_status: protocol_reorient_state_status(applied.state_status),
|
||||
state_revision: applied.state_revision,
|
||||
decision: thread_epiphany_reorient_decision(applied.decision),
|
||||
decision: protocol_reorient_decision(applied.decision),
|
||||
revision: applied.revision,
|
||||
changed_fields: protocol_changed_fields,
|
||||
epiphany_state: epiphany_state.clone(),
|
||||
job: thread_epiphany_job_from_surface(
|
||||
job: protocol_job_from_surface(
|
||||
applied.job,
|
||||
Some(applied.launcher_job_id),
|
||||
Some(applied.backend_job_id),
|
||||
|
|
@ -670,7 +663,7 @@ impl CodexMessageProcessor {
|
|||
revision: applied.revision,
|
||||
changed_fields: protocol_changed_fields,
|
||||
epiphany_state: epiphany_state.clone(),
|
||||
job: thread_epiphany_job_from_surface(
|
||||
job: protocol_job_from_surface(
|
||||
applied.job,
|
||||
Some(applied.launcher_job_id),
|
||||
Some(applied.backend_job_id),
|
||||
|
|
@ -740,7 +733,7 @@ impl CodexMessageProcessor {
|
|||
revision: applied.revision,
|
||||
changed_fields: protocol_changed_fields,
|
||||
epiphany_state: epiphany_state.clone(),
|
||||
job: thread_epiphany_job_from_surface(applied.job, None, None),
|
||||
job: protocol_job_from_surface(applied.job, None, None),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
|
@ -754,165 +747,6 @@ impl CodexMessageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_job_from_surface(
|
||||
job: EpiphanyJobView,
|
||||
launcher_job_id: Option<String>,
|
||||
backend_job_id_override: Option<String>,
|
||||
) -> ThreadEpiphanyJob {
|
||||
ThreadEpiphanyJob {
|
||||
id: job.id,
|
||||
kind: match job.kind {
|
||||
EpiphanyJobKind::Indexing => ThreadEpiphanyJobKind::Indexing,
|
||||
EpiphanyJobKind::Remap => ThreadEpiphanyJobKind::Remap,
|
||||
EpiphanyJobKind::Verification => ThreadEpiphanyJobKind::Verification,
|
||||
EpiphanyJobKind::Specialist => ThreadEpiphanyJobKind::Specialist,
|
||||
},
|
||||
scope: job.scope,
|
||||
owner_role: job.owner_role,
|
||||
launcher_job_id,
|
||||
authority_scope: job.authority_scope,
|
||||
backend_job_id: backend_job_id_override.or(job.runtime_job_id),
|
||||
status: match job.status {
|
||||
EpiphanyJobStatus::Idle => ThreadEpiphanyJobStatus::Idle,
|
||||
EpiphanyJobStatus::Needed => ThreadEpiphanyJobStatus::Needed,
|
||||
EpiphanyJobStatus::Pending => ThreadEpiphanyJobStatus::Pending,
|
||||
EpiphanyJobStatus::Running => ThreadEpiphanyJobStatus::Running,
|
||||
EpiphanyJobStatus::Completed => ThreadEpiphanyJobStatus::Completed,
|
||||
EpiphanyJobStatus::Failed => ThreadEpiphanyJobStatus::Failed,
|
||||
EpiphanyJobStatus::Cancelled => ThreadEpiphanyJobStatus::Cancelled,
|
||||
EpiphanyJobStatus::Blocked => ThreadEpiphanyJobStatus::Blocked,
|
||||
EpiphanyJobStatus::Unavailable => ThreadEpiphanyJobStatus::Unavailable,
|
||||
},
|
||||
items_processed: job.items_processed,
|
||||
items_total: job.items_total,
|
||||
progress_note: job.progress_note,
|
||||
last_checkpoint_at_unix_seconds: job.last_checkpoint_at_unix_seconds,
|
||||
blocking_reason: job.blocking_reason,
|
||||
active_thread_ids: job.active_thread_ids,
|
||||
linked_subgoal_ids: job.linked_subgoal_ids,
|
||||
linked_graph_node_ids: job.linked_graph_node_ids,
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_state_status(
|
||||
status: EpiphanyReorientStateStatus,
|
||||
) -> ThreadEpiphanyReorientStateStatus {
|
||||
match status {
|
||||
EpiphanyReorientStateStatus::Missing => ThreadEpiphanyReorientStateStatus::Missing,
|
||||
EpiphanyReorientStateStatus::Ready => ThreadEpiphanyReorientStateStatus::Ready,
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_source(source: EpiphanySurfaceSource) -> ThreadEpiphanyReorientSource {
|
||||
match source {
|
||||
EpiphanySurfaceSource::Stored => ThreadEpiphanyReorientSource::Stored,
|
||||
EpiphanySurfaceSource::Live => ThreadEpiphanyReorientSource::Live,
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_decision(
|
||||
decision: EpiphanyReorientDecision,
|
||||
) -> ThreadEpiphanyReorientDecision {
|
||||
ThreadEpiphanyReorientDecision {
|
||||
action: match decision.action {
|
||||
EpiphanyReorientAction::Resume => ThreadEpiphanyReorientAction::Resume,
|
||||
EpiphanyReorientAction::Regather => ThreadEpiphanyReorientAction::Regather,
|
||||
},
|
||||
checkpoint_status: match decision.checkpoint_status {
|
||||
EpiphanyReorientCheckpointStatus::Missing => {
|
||||
ThreadEpiphanyReorientCheckpointStatus::Missing
|
||||
}
|
||||
EpiphanyReorientCheckpointStatus::ResumeReady => {
|
||||
ThreadEpiphanyReorientCheckpointStatus::ResumeReady
|
||||
}
|
||||
EpiphanyReorientCheckpointStatus::RegatherRequired => {
|
||||
ThreadEpiphanyReorientCheckpointStatus::RegatherRequired
|
||||
}
|
||||
},
|
||||
checkpoint_id: decision.checkpoint_id,
|
||||
pressure_level: match decision.pressure_level {
|
||||
EpiphanyReorientPressureLevel::Unknown => ThreadEpiphanyPressureLevel::Unknown,
|
||||
EpiphanyReorientPressureLevel::Low => ThreadEpiphanyPressureLevel::Low,
|
||||
EpiphanyReorientPressureLevel::Medium => ThreadEpiphanyPressureLevel::Elevated,
|
||||
EpiphanyReorientPressureLevel::High => ThreadEpiphanyPressureLevel::High,
|
||||
EpiphanyReorientPressureLevel::Critical => ThreadEpiphanyPressureLevel::Critical,
|
||||
},
|
||||
retrieval_status: thread_epiphany_reorient_retrieval_status(decision.retrieval_status),
|
||||
graph_status: thread_epiphany_reorient_graph_status(decision.graph_status),
|
||||
watcher_status: thread_epiphany_reorient_watcher_status(decision.watcher_status),
|
||||
reasons: decision
|
||||
.reasons
|
||||
.into_iter()
|
||||
.map(thread_epiphany_reorient_reason)
|
||||
.collect(),
|
||||
checkpoint_dirty_paths: decision.checkpoint_dirty_paths,
|
||||
checkpoint_changed_paths: decision.checkpoint_changed_paths,
|
||||
active_frontier_node_ids: decision.active_frontier_node_ids,
|
||||
next_action: decision.next_action,
|
||||
note: decision.note,
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_retrieval_status(
|
||||
status: EpiphanyReorientFreshnessStatus,
|
||||
) -> ThreadEpiphanyRetrievalFreshnessStatus {
|
||||
match status {
|
||||
EpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyRetrievalFreshnessStatus::Missing,
|
||||
EpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyRetrievalFreshnessStatus::Ready,
|
||||
EpiphanyReorientFreshnessStatus::Dirty => ThreadEpiphanyRetrievalFreshnessStatus::Indexing,
|
||||
EpiphanyReorientFreshnessStatus::Stale | EpiphanyReorientFreshnessStatus::Changed => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Stale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_graph_status(
|
||||
status: EpiphanyReorientFreshnessStatus,
|
||||
) -> ThreadEpiphanyGraphFreshnessStatus {
|
||||
match status {
|
||||
EpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyGraphFreshnessStatus::Missing,
|
||||
EpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyGraphFreshnessStatus::Ready,
|
||||
EpiphanyReorientFreshnessStatus::Dirty
|
||||
| EpiphanyReorientFreshnessStatus::Stale
|
||||
| EpiphanyReorientFreshnessStatus::Changed => ThreadEpiphanyGraphFreshnessStatus::Stale,
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_watcher_status(
|
||||
status: EpiphanyReorientFreshnessStatus,
|
||||
) -> ThreadEpiphanyInvalidationStatus {
|
||||
match status {
|
||||
EpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyInvalidationStatus::Unavailable,
|
||||
EpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyInvalidationStatus::Clean,
|
||||
EpiphanyReorientFreshnessStatus::Dirty
|
||||
| EpiphanyReorientFreshnessStatus::Stale
|
||||
| EpiphanyReorientFreshnessStatus::Changed => ThreadEpiphanyInvalidationStatus::Changed,
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_reorient_reason(reason: EpiphanyReorientReason) -> ThreadEpiphanyReorientReason {
|
||||
match reason {
|
||||
EpiphanyReorientReason::MissingState => ThreadEpiphanyReorientReason::MissingState,
|
||||
EpiphanyReorientReason::MissingCheckpoint => {
|
||||
ThreadEpiphanyReorientReason::MissingCheckpoint
|
||||
}
|
||||
EpiphanyReorientReason::CheckpointReady => ThreadEpiphanyReorientReason::CheckpointReady,
|
||||
EpiphanyReorientReason::CheckpointRequestedRegather => {
|
||||
ThreadEpiphanyReorientReason::CheckpointRequestedRegather
|
||||
}
|
||||
EpiphanyReorientReason::CheckpointPathsDirty => {
|
||||
ThreadEpiphanyReorientReason::CheckpointPathsDirty
|
||||
}
|
||||
EpiphanyReorientReason::CheckpointPathsChanged => {
|
||||
ThreadEpiphanyReorientReason::CheckpointPathsChanged
|
||||
}
|
||||
EpiphanyReorientReason::FrontierChanged => ThreadEpiphanyReorientReason::FrontierChanged,
|
||||
EpiphanyReorientReason::UnanchoredCheckpointWhileStateStale => {
|
||||
ThreadEpiphanyReorientReason::UnanchoredCheckpointWhileStateStale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn thread_epiphany_retrieval_state(thread: &CodexThread) -> EpiphanyRetrievalState {
|
||||
let config = thread.config_snapshot().await;
|
||||
let codex_home = thread.codex_home().await;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@ use codex_app_server_protocol::*;
|
|||
use codex_core::CodexThread;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::protocol::EpiphanyRetrievalState;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyFreshnessSurface;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyGraphFreshnessStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyInvalidationStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanyRetrievalFreshnessStatus;
|
||||
use epiphany_codex_bridge::cultnet::EpiphanySurfaceSource;
|
||||
use epiphany_codex_bridge::invalidation::epiphany_freshness_watcher_snapshot;
|
||||
use epiphany_codex_bridge::launch::EPIPHANY_REORIENT_LAUNCH_BINDING_ID;
|
||||
|
|
@ -17,6 +13,7 @@ use epiphany_codex_bridge::protocol_edge::core_epiphany_view_needs_runtime_store
|
|||
use epiphany_codex_bridge::protocol_edge::default_core_epiphany_view_lenses;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_context_params_to_core;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_distill_params_to_core;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_freshness_response_from_surface;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_graph_query_to_core;
|
||||
use epiphany_codex_bridge::protocol_edge::protocol_view_lenses_to_core;
|
||||
use epiphany_codex_bridge::results::map_core_role_result_role_id;
|
||||
|
|
@ -281,7 +278,7 @@ impl CodexMessageProcessor {
|
|||
.as_ref()
|
||||
.map(epiphany_freshness_watcher_snapshot),
|
||||
});
|
||||
let response = thread_epiphany_freshness_response_from_surface(surface);
|
||||
let response = protocol_freshness_response_from_surface(surface);
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
}
|
||||
|
||||
|
|
@ -584,76 +581,6 @@ impl CodexMessageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
fn thread_epiphany_freshness_response_from_surface(
|
||||
surface: EpiphanyFreshnessSurface,
|
||||
) -> ThreadEpiphanyFreshnessResponse {
|
||||
ThreadEpiphanyFreshnessResponse {
|
||||
thread_id: surface.thread_id,
|
||||
source: match surface.source {
|
||||
EpiphanySurfaceSource::Stored => ThreadEpiphanyFreshnessSource::Stored,
|
||||
EpiphanySurfaceSource::Live => ThreadEpiphanyFreshnessSource::Live,
|
||||
},
|
||||
state_revision: surface.state_revision,
|
||||
retrieval: ThreadEpiphanyRetrievalFreshness {
|
||||
status: match surface.retrieval.status {
|
||||
EpiphanyRetrievalFreshnessStatus::Missing => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Missing
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Ready => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Ready
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Stale => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Stale
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Indexing => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Indexing
|
||||
}
|
||||
EpiphanyRetrievalFreshnessStatus::Unavailable => {
|
||||
ThreadEpiphanyRetrievalFreshnessStatus::Unavailable
|
||||
}
|
||||
},
|
||||
semantic_available: surface.retrieval.semantic_available,
|
||||
last_indexed_at_unix_seconds: surface.retrieval.last_indexed_at_unix_seconds,
|
||||
indexed_file_count: surface.retrieval.indexed_file_count,
|
||||
indexed_chunk_count: surface.retrieval.indexed_chunk_count,
|
||||
dirty_paths: surface.retrieval.dirty_paths,
|
||||
note: surface.retrieval.note,
|
||||
},
|
||||
graph: ThreadEpiphanyGraphFreshness {
|
||||
status: match surface.graph.status {
|
||||
EpiphanyGraphFreshnessStatus::Missing => {
|
||||
ThreadEpiphanyGraphFreshnessStatus::Missing
|
||||
}
|
||||
EpiphanyGraphFreshnessStatus::Ready => ThreadEpiphanyGraphFreshnessStatus::Ready,
|
||||
EpiphanyGraphFreshnessStatus::Stale => ThreadEpiphanyGraphFreshnessStatus::Stale,
|
||||
},
|
||||
graph_freshness: surface.graph.graph_freshness,
|
||||
checkpoint_id: surface.graph.checkpoint_id,
|
||||
dirty_path_count: surface.graph.dirty_path_count,
|
||||
dirty_paths: surface.graph.dirty_paths,
|
||||
open_question_count: surface.graph.open_question_count,
|
||||
open_gap_count: surface.graph.open_gap_count,
|
||||
note: surface.graph.note,
|
||||
},
|
||||
watcher: ThreadEpiphanyInvalidationInput {
|
||||
status: match surface.watcher.status {
|
||||
EpiphanyInvalidationStatus::Unavailable => {
|
||||
ThreadEpiphanyInvalidationStatus::Unavailable
|
||||
}
|
||||
EpiphanyInvalidationStatus::Clean => ThreadEpiphanyInvalidationStatus::Clean,
|
||||
EpiphanyInvalidationStatus::Changed => ThreadEpiphanyInvalidationStatus::Changed,
|
||||
},
|
||||
watched_root: surface.watcher.watched_root,
|
||||
observed_at_unix_seconds: surface.watcher.observed_at_unix_seconds,
|
||||
changed_path_count: surface.watcher.changed_path_count,
|
||||
changed_paths: surface.watcher.changed_paths,
|
||||
graph_node_ids: surface.watcher.graph_node_ids,
|
||||
active_frontier_node_ids: surface.watcher.active_frontier_node_ids,
|
||||
note: surface.watcher.note,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn thread_epiphany_retrieval_state(thread: &CodexThread) -> EpiphanyRetrievalState {
|
||||
let config = thread.config_snapshot().await;
|
||||
let codex_home = thread.codex_home().await;
|
||||
|
|
|
|||
Reference in a new issue