feat: propagate workspace prompt revisions
This commit is contained in:
@@ -45,6 +45,7 @@ use worker_runtime::http_server::{
|
||||
RuntimeHttpWorkerLifecycleResponse, RuntimeHttpWorkerResponse,
|
||||
RuntimeHttpWorkerWorkspaceApiRequest, RuntimeHttpWorkersResponse,
|
||||
RuntimeHttpWorkingDirectoriesResponse, RuntimeHttpWorkingDirectoryResponse,
|
||||
RuntimeHttpWorkspacePromptProjectionRequest, RuntimeHttpWorkspacePromptProjectionResponse,
|
||||
};
|
||||
use worker_runtime::identity::{
|
||||
RuntimeWorkerRef, WorkerId as EmbeddedWorkerId, WorkerRef as EmbeddedWorkerRef,
|
||||
@@ -778,6 +779,13 @@ pub trait WorkspaceWorkerRuntime: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
fn observe_workspace_prompt_projection(
|
||||
&self,
|
||||
_projection: worker::WorkspacePromptProjection,
|
||||
) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn sync_config_bundle(&self, _bundle: ConfigBundle) -> ConfigBundleSyncResult {
|
||||
ConfigBundleSyncResult {
|
||||
state: WorkerOperationState::Unsupported,
|
||||
@@ -1185,6 +1193,36 @@ impl RuntimeRegistry {
|
||||
Ok(runtime.replace_worker_workspace_api(worker_id, workspace_api))
|
||||
}
|
||||
|
||||
pub fn observe_workspace_prompt_projection(
|
||||
&self,
|
||||
projection: worker::WorkspacePromptProjection,
|
||||
) -> Vec<RuntimeDiagnostic> {
|
||||
let runtimes = self
|
||||
.runtimes
|
||||
.read()
|
||||
.map(|runtimes| runtimes.clone())
|
||||
.unwrap_or_default();
|
||||
runtimes
|
||||
.into_iter()
|
||||
.filter_map(|runtime| {
|
||||
runtime
|
||||
.observe_workspace_prompt_projection(projection.clone())
|
||||
.err()
|
||||
.map(|message| {
|
||||
diagnostic(
|
||||
"workspace_prompt_projection_notification_failed",
|
||||
DiagnosticSeverity::Warning,
|
||||
format!(
|
||||
"runtime '{}' rejected Workspace Prompt projection revision {}: {message}",
|
||||
runtime.runtime_id(), projection.config_revision
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
.take(MAX_DIAGNOSTICS)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn spawn_worker(
|
||||
&self,
|
||||
runtime_id: &str,
|
||||
@@ -2040,6 +2078,15 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
fn observe_workspace_prompt_projection(
|
||||
&self,
|
||||
projection: worker::WorkspacePromptProjection,
|
||||
) -> Result<(), String> {
|
||||
self.runtime
|
||||
.observe_workspace_prompt_projection(projection)
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
fn sync_config_bundle(&self, bundle: ConfigBundle) -> ConfigBundleSyncResult {
|
||||
match self.runtime.store_config_bundle(bundle) {
|
||||
Ok(availability) => ConfigBundleSyncResult {
|
||||
@@ -3155,6 +3202,18 @@ impl WorkspaceWorkerRuntime for RemoteWorkerRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
fn observe_workspace_prompt_projection(
|
||||
&self,
|
||||
projection: worker::WorkspacePromptProjection,
|
||||
) -> Result<(), String> {
|
||||
self.post_json::<_, RuntimeHttpWorkspacePromptProjectionResponse>(
|
||||
"/v1/workspace-prompt-projections",
|
||||
&RuntimeHttpWorkspacePromptProjectionRequest { projection },
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(|error| error.message)
|
||||
}
|
||||
|
||||
fn sync_config_bundle(&self, bundle: ConfigBundle) -> ConfigBundleSyncResult {
|
||||
let request = RuntimeHttpConfigBundleSyncRequest { bundle };
|
||||
match self.post_json::<_, RuntimeHttpConfigBundleAvailabilityResponse>(
|
||||
@@ -4507,6 +4566,7 @@ mod tests {
|
||||
runtime_id: String,
|
||||
host_id: String,
|
||||
workers: Vec<WorkerSummary>,
|
||||
observed_prompt_revisions: Arc<Mutex<Vec<u64>>>,
|
||||
}
|
||||
|
||||
impl FixtureRuntime {
|
||||
@@ -4542,6 +4602,7 @@ mod tests {
|
||||
working_directory: None,
|
||||
diagnostics: Vec::new(),
|
||||
}],
|
||||
observed_prompt_revisions: Arc::new(Mutex::new(Vec::new())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4551,6 +4612,17 @@ mod tests {
|
||||
&self.runtime_id
|
||||
}
|
||||
|
||||
fn observe_workspace_prompt_projection(
|
||||
&self,
|
||||
projection: worker::WorkspacePromptProjection,
|
||||
) -> Result<(), String> {
|
||||
self.observed_prompt_revisions
|
||||
.lock()
|
||||
.map_err(|_| "prompt projection observations poisoned".to_string())?
|
||||
.push(projection.config_revision);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn runtime_summary(&self, _limit: usize) -> RuntimeSummary {
|
||||
RuntimeSummary {
|
||||
runtime_id: self.runtime_id.clone(),
|
||||
@@ -4647,6 +4719,36 @@ mod tests {
|
||||
assert_eq!(from_runtime_a.label, "worker from runtime a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_broadcasts_workspace_prompt_projection_revisions() {
|
||||
let runtime =
|
||||
FixtureRuntime::with_worker("runtime-a", "host-a", "worker-a", "worker from runtime a");
|
||||
let observed = runtime.observed_prompt_revisions.clone();
|
||||
let registry = RuntimeRegistry::new(vec![Arc::new(runtime)]);
|
||||
let catalog = worker::EffectivePromptCatalog::new(
|
||||
std::collections::BTreeMap::from([(
|
||||
"default".to_string(),
|
||||
"workspace prompt".to_string(),
|
||||
)]),
|
||||
12,
|
||||
"schema",
|
||||
"toolchain",
|
||||
)
|
||||
.unwrap();
|
||||
let projection = worker::WorkspacePromptProjection::new(
|
||||
"workspace-a",
|
||||
"source-12",
|
||||
catalog.catalog_digest.clone(),
|
||||
catalog,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let diagnostics = registry.observe_workspace_prompt_projection(projection);
|
||||
|
||||
assert!(diagnostics.is_empty());
|
||||
assert_eq!(*observed.lock().unwrap(), vec![12]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_worker_list_can_be_scoped_by_runtime_id() {
|
||||
let registry = RuntimeRegistry::new(vec![
|
||||
|
||||
@@ -2673,6 +2673,14 @@ async fn scoped_commit_workspace_config_tree(
|
||||
let state = api
|
||||
.config_store
|
||||
.commit_evaluated_workspace_config(&path.workspace_id, &candidate)?;
|
||||
if let Ok(projection) = api
|
||||
.prompt_projection_cache
|
||||
.resolve(&path.workspace_id, &state)
|
||||
{
|
||||
let _diagnostics = api
|
||||
.runtime
|
||||
.observe_workspace_prompt_projection((*projection).clone());
|
||||
}
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(WorkspaceConfigTreeResponse {
|
||||
|
||||
Reference in New Issue
Block a user