refactor: unify runtime/tool requirements via CompilerExtension trait#211
Conversation
🔍 Rust PR ReviewSummary: Looks good — clean refactor with solid test coverage. Two issues worth addressing before merge. Findings🐛 Bugs / Logic Issues
|
Introduce a CompilerExtension trait that runtimes and first-party tools implement to declare their compilation requirements (network hosts, bash commands, prompt supplements, prepare steps, MCPG entries). Previously, each runtime/tool required scattered special-case code across standalone.rs, common.rs, and other files. Now: - LeanExtension: declares hosts, bash cmds, install steps, prompt - AzureDevOpsExtension: declares hosts, MCPG entry, validation - CacheMemoryExtension: declares download steps, prompt supplement The compiler collects all enabled extensions via collect_extensions() and iterates over them generically -- no more bespoke if-blocks. Adding a new runtime or tool is now a 2-step process: 1. Implement CompilerExtension 2. Add to collect_extensions() MCPG types (McpgServerConfig, McpgConfig, etc.) moved from standalone.rs to extensions.rs for shared access. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
58610c1 to
d827870
Compare
- Add validation loop to OneESCompiler (bug: Lean/ADO warnings were silently dropped for target: 1es agents) - Add debug_assert on display_name in wrap_prompt_append to guard against future extension names with shell/YAML metacharacters - Document why CacheMemoryExtension.config is #[allow(dead_code)] (options consumed at Stage 2, not compile time) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Clean refactor with one security concern and one behavioral change worth noting. Findings🔒 Security Concerns
|
Extensions now declare their phase via phase() -> ExtensionPhase. collect_extensions() sorts by phase using stable sort, guaranteeing runtimes install before tools — critical when a tool depends on a runtime (e.g., uv requires Python to be installed first). Phases: Runtime (0) → Tool (1). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace debug_assert! with anyhow::ensure! in wrap_prompt_append so unsafe display_name characters are rejected in release builds too. Function now returns Result<String>. - Add doc comment to validate() explaining that inferred_org is not available at validation time — org-dependent checks belong in mcpg_servers() which receives the fully populated CompileContext. - Add test for unsafe display_name rejection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Clean, well-structured refactor — looks good with a few minor issues worth fixing before merge. Findings🐛 Bugs / Logic Issues
|
Summary
Introduces a
CompilerExtensiontrait that runtimes and first-party tools implement to declare their compilation requirements. Replaces scattered special-caseifblocks across the compiler with a single generic collection loop.Problem
Adding a new runtime or tool required touching 5+ files with bespoke integration code:
standalone.rs— network hosts, MCPG config, prepare steps, prompt injectioncommon.rs— bash command allowlistallowed_hosts.rs— domain declarationstypes.rs— config structsSolution
A unified
CompilerExtensiontrait (src/compile/extensions.rs) with methods:required_hosts()required_bash_commands()--allow-tool shell(cmd)flagsprompt_supplement()prepare_steps()mcpg_servers()validate()Extensions implemented
LeanExtension— hosts, bash cmds (lean/lake/elan), install steps, prompt, bash-disabled warningAzureDevOpsExtension— hosts, MCPG container entry (with org inference), duplicate MCP warningCacheMemoryExtension— download/restore steps, prompt supplementAdding a new runtime or tool
CompilerExtensionfor your config structcollect_extensions()No other files need modification.
Regression testing
Built v0.11.0 baseline and compared pipeline YAML output:
sample-agent.md(no extensions)lean-verifier.md(Lean + cache-memory)Changes
src/compile/extensions.rs(trait, 3 impls, MCPG types, 19 tests)standalone.rs(−180 lines of special-case code → generic loops)common.rs(generate_copilot_paramsaccepts extensions)onees.rs(passes extensions togenerate_copilot_params)AGENTS.md(updated developer docs)