fix: remove config bundle restore dependency
This commit is contained in:
@@ -252,15 +252,25 @@ pub fn selector_for_workspace_candidate(
|
||||
fn validate_prompt_projection_matches_state(
|
||||
workspace_id: &str,
|
||||
state: &WorkspaceConfigState,
|
||||
projection: &crate::prompt_settings::WorkspacePromptProjection,
|
||||
projection: &worker::WorkspacePromptProjection,
|
||||
) -> Result<()> {
|
||||
if !projection.matches(workspace_id, state) {
|
||||
return Err(Error::Config(
|
||||
"Prompt projection identity does not match Workspace config state".to_string(),
|
||||
));
|
||||
}
|
||||
projection
|
||||
.validate()
|
||||
.map_err(|error| Error::Config(error.to_string()))?;
|
||||
let prompt_catalog = projection.catalog();
|
||||
let mismatches = [
|
||||
(
|
||||
projection.workspace_id != workspace_id,
|
||||
"workspace identity",
|
||||
),
|
||||
(
|
||||
projection.source_digest != state.snapshot.digest,
|
||||
"source digest",
|
||||
),
|
||||
(
|
||||
projection.projection_digest != prompt_catalog.catalog_digest,
|
||||
"projection digest",
|
||||
),
|
||||
(
|
||||
prompt_catalog.config_revision != state.snapshot.revision,
|
||||
"config revision",
|
||||
@@ -353,7 +363,7 @@ pub fn build_virtual_profile_config_bundle_with_prompt_projection(
|
||||
workspace_id: &str,
|
||||
workspace_created_at: &str,
|
||||
selector: &str,
|
||||
prompt_projection: &crate::prompt_settings::WorkspacePromptProjection,
|
||||
prompt_projection: &worker::WorkspacePromptProjection,
|
||||
) -> Result<Option<ConfigBundle>> {
|
||||
validate_prompt_projection_matches_state(workspace_id, state, prompt_projection)?;
|
||||
let prompt_catalog = prompt_projection.catalog().clone();
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
|
||||
use config_source::{ConfigProjectionValidator, ConfigSchemaContribution};
|
||||
use worker::{EffectivePromptCatalog, prompt_schema_source};
|
||||
use worker::{EffectivePromptCatalog, WorkspacePromptProjection, prompt_schema_source};
|
||||
|
||||
use crate::config_source::{
|
||||
WorkspaceConfigSchemaProvider, WorkspaceConfigState, evaluate_workspace_config_state,
|
||||
@@ -13,6 +13,7 @@ use crate::{Error, Result};
|
||||
struct PromptProjectionCacheKey {
|
||||
workspace_id: String,
|
||||
config_revision: u64,
|
||||
source_digest: String,
|
||||
projection_digest: String,
|
||||
schema_fingerprint: String,
|
||||
toolchain_fingerprint: String,
|
||||
@@ -23,6 +24,7 @@ impl PromptProjectionCacheKey {
|
||||
Self {
|
||||
workspace_id: workspace_id.to_string(),
|
||||
config_revision: state.snapshot.revision,
|
||||
source_digest: state.snapshot.digest.clone(),
|
||||
projection_digest: state.projection_digest.clone(),
|
||||
schema_fingerprint: state.contract.schema_bundle.fingerprint.clone(),
|
||||
toolchain_fingerprint: state.contract.fingerprint.clone(),
|
||||
@@ -30,22 +32,6 @@ impl PromptProjectionCacheKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WorkspacePromptProjection {
|
||||
identity: PromptProjectionCacheKey,
|
||||
catalog: EffectivePromptCatalog,
|
||||
}
|
||||
|
||||
impl WorkspacePromptProjection {
|
||||
pub fn catalog(&self) -> &EffectivePromptCatalog {
|
||||
&self.catalog
|
||||
}
|
||||
|
||||
pub fn matches(&self, workspace_id: &str, state: &WorkspaceConfigState) -> bool {
|
||||
self.identity == PromptProjectionCacheKey::new(workspace_id, state)
|
||||
}
|
||||
}
|
||||
|
||||
type PromptProjectionCell = OnceLock<std::result::Result<Arc<WorkspacePromptProjection>, String>>;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -242,10 +228,14 @@ pub fn project_workspace_prompt_projection(
|
||||
workspace_id: &str,
|
||||
state: &WorkspaceConfigState,
|
||||
) -> Result<WorkspacePromptProjection> {
|
||||
Ok(WorkspacePromptProjection {
|
||||
identity: PromptProjectionCacheKey::new(workspace_id, state),
|
||||
catalog: project_prompts_from_workspace_config(state)?,
|
||||
})
|
||||
let catalog = project_prompts_from_workspace_config(state)?;
|
||||
WorkspacePromptProjection::new(
|
||||
workspace_id,
|
||||
state.snapshot.digest.clone(),
|
||||
catalog.catalog_digest.clone(),
|
||||
catalog,
|
||||
)
|
||||
.map_err(|error| Error::RegistryInconsistency(error.to_string()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1243,6 +1243,10 @@ pub fn build_router(api: WorkspaceApi) -> Router {
|
||||
"/api/w/{workspace_id}/config/source-tree",
|
||||
get(scoped_get_workspace_config_tree),
|
||||
)
|
||||
.route(
|
||||
"/api/w/{workspace_id}/config/projections/prompts",
|
||||
get(scoped_get_prompt_projection),
|
||||
)
|
||||
.route(
|
||||
"/api/w/{workspace_id}/config/source-tree/commit",
|
||||
post(scoped_commit_workspace_config_tree),
|
||||
@@ -2581,6 +2585,25 @@ struct WorkspaceConfigEntryPath {
|
||||
path: String,
|
||||
}
|
||||
|
||||
async fn scoped_get_prompt_projection(
|
||||
State(api): State<WorkspaceApi>,
|
||||
AxumPath(path): AxumPath<ScopedWorkspacePath>,
|
||||
) -> ApiResult<Json<worker::WorkspacePromptProjection>> {
|
||||
validate_workspace_scope(&api, &path.workspace_id)?;
|
||||
let state = api
|
||||
.config_store
|
||||
.load_workspace_config(&path.workspace_id)?
|
||||
.ok_or_else(|| {
|
||||
ApiError::from(Error::InvalidInput(
|
||||
"Workspace config is not initialized".to_string(),
|
||||
))
|
||||
})?;
|
||||
let projection = api
|
||||
.prompt_projection_cache
|
||||
.resolve(&path.workspace_id, &state)?;
|
||||
Ok(Json(projection.as_ref().clone()))
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct WorkspaceConfigTreeResponse {
|
||||
snapshot: ConfigTreeSnapshot,
|
||||
|
||||
Reference in New Issue
Block a user