From d149f7e9364f666b48e816edb46176c0c5f7d26b Mon Sep 17 00:00:00 2001 From: Hare Date: Fri, 10 Jul 2026 04:18:14 +0900 Subject: [PATCH] runtime: namespace spawned worker names --- crates/worker-runtime/src/worker_backend.rs | 45 ++++++++++++++++++++- crates/workspace-server/src/hosts.rs | 5 +-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/crates/worker-runtime/src/worker_backend.rs b/crates/worker-runtime/src/worker_backend.rs index 2384fa13..e11a07b3 100644 --- a/crates/worker-runtime/src/worker_backend.rs +++ b/crates/worker-runtime/src/worker_backend.rs @@ -137,7 +137,11 @@ impl ProfileRuntimeWorkerFactory { } fn runtime_worker_name(request: &WorkerExecutionSpawnRequest) -> String { - request.worker_ref.worker_id.to_string() + format!( + "runtime-{}-{}", + sanitize_worker_name_component(request.worker_ref.runtime_id.as_str()), + request.worker_ref.worker_id + ) } fn runtime_profile_value( @@ -213,6 +217,19 @@ impl ProfileRuntimeWorkerFactory { } } +fn sanitize_worker_name_component(value: &str) -> String { + value + .chars() + .map(|ch| { + if ch.is_ascii_alphanumeric() || matches!(ch, '-' | '_') { + ch + } else { + '-' + } + }) + .collect() +} + #[cfg(feature = "http-server")] async fn fetch_profile_source_archive_http( location: &ProfileSourceArchiveHttpRef, @@ -800,6 +817,7 @@ mod tests { ConfigBundleRef, CreateWorkerRequest, DirtyStatePolicy, MaterializerKind, ProfileSelector, RepositorySelector, WorkingDirectoryRepository, WorkingDirectoryRequest, }; + use crate::execution::WorkerExecutionContext; use crate::identity::RuntimeId; use crate::management::RuntimeOptions; use crate::observation::{TranscriptQuery, TranscriptRole}; @@ -1021,6 +1039,31 @@ mod tests { } } + #[test] + fn runtime_worker_name_is_namespaced_by_runtime_id() { + let runtime_id = RuntimeId::new("arc:remote".to_string()).unwrap(); + let worker_ref = crate::identity::WorkerRef::new( + runtime_id, + crate::identity::WorkerId::new("worker-00000001".to_string()).unwrap(), + ); + let request = WorkerExecutionSpawnRequest { + worker_ref: worker_ref.clone(), + request: create_request("worker-00000001"), + context: WorkerExecutionContext::new(worker_ref, Arc::new(|_, _| panic!("unused"))), + working_directory: None, + config_bundle: None, + }; + + assert_eq!( + ProfileRuntimeWorkerFactory::runtime_worker_name(&request), + "runtime-arc-remote-worker-00000001" + ); + assert_ne!( + ProfileRuntimeWorkerFactory::runtime_worker_name(&request), + "worker-00000001" + ); + } + #[tokio::test] async fn embedded_profile_source_archive_does_not_require_backend_resource_fetch() { let factory = ProfileRuntimeWorkerFactory::new(tempfile::tempdir().unwrap().path()); diff --git a/crates/workspace-server/src/hosts.rs b/crates/workspace-server/src/hosts.rs index a3c737b8..d9463ecb 100644 --- a/crates/workspace-server/src/hosts.rs +++ b/crates/workspace-server/src/hosts.rs @@ -3348,10 +3348,7 @@ mod tests { .resolve_profile(&selector_key, root.path(), "embedded-test-worker") .unwrap(); assert_eq!(manifest.worker.name, "embedded-test-worker"); - assert_eq!( - manifest.model.ref_.as_deref(), - Some("codex-oauth/gpt-5.5") - ); + assert_eq!(manifest.model.ref_.as_deref(), Some("codex-oauth/gpt-5.5")); } }