| 297 | } |
| 298 | |
| 299 | fn build( |
| 300 | workspace: String, |
| 301 | command_env: Option<HashMap<String, String>>, |
| 302 | artifact_limits: ArtifactStoreLimits, |
| 303 | workspace_services: Arc<crate::workspace::WorkspaceServices>, |
| 304 | ) -> Self { |
| 305 | let workspace_path = PathBuf::from(&workspace); |
| 306 | let command_env = command_env.map(Arc::new); |
| 307 | let registry = Arc::new(ToolRegistry::with_artifact_limits_and_workspace_services( |
| 308 | workspace_path.clone(), |
| 309 | artifact_limits, |
| 310 | Arc::clone(&workspace_services), |
| 311 | )); |
| 312 | if let Some(env) = command_env.clone() { |
| 313 | registry.set_command_env(env); |
| 314 | } |
| 315 | |
| 316 | // Register native Rust built-in tools — only those whose required |
| 317 | // workspace capability is available, so the model never sees a tool |
| 318 | // the backend cannot service. |
| 319 | builtin::register_builtins(®istry, &workspace_services.capabilities()); |
| 320 | // Batch tool requires Arc<ToolRegistry>, registered separately |
| 321 | builtin::register_batch(®istry); |
| 322 | builtin::register_program(®istry); |
| 323 | |
| 324 | Self { |
| 325 | workspace: workspace_path, |
| 326 | registry, |
| 327 | file_history: Arc::new(FileHistory::new(500)), |
| 328 | command_env, |
| 329 | workspace_services, |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | fn check_workspace_boundary( |
| 334 | name: &str, |