Skip to main content

add-backend

Guide for adding a backend (Rust or Python) to the agent-sec-core security middleware. Use when creating new backends, integrating Rust or Python code into the security middleware, or extending with new backend actions.

설치로 이동

소스 정보

저장소
agentic-os-org/ANOLISA
최근 소스 활동
2026년 4월 26일 09:25
감지된 SKILL.md 언어
영어
스타
613
포크
104

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
5 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
add-backend
description
Guide for adding a backend (Rust or Python) to the agent-sec-core security middleware. Use when creating new backends, integrating Rust or Python code into the security middleware, or extending with new backend actions.
arguments
[{"name":"backend_name","description":"Name of the new backend (e.g. 'code_verify'). Spaces are converted to underscores for code identifiers.","required":true},{"name":"backend_type","description":"Backend implementation type: 'rust' or 'python'","required":true},{"name":"module_path","description":"For python type: module path (e.g. 'agent_sec_cli.code_verify.verifier'). Required when backend_type=python.","required":false}]
# Adding a Backend to Security Middleware This skill walks through the **complete, end-to-end** process of adding a backend (Rust or Python) to the security middleware, wiring it into the router, and exposing it through the CLI. > **Unified interface**: Both Rust and Python backends implement the same > `execute(ctx, **kwargs) → ActionResult` contract. The middleware doesn't care > about the implementation language. ## Backend Type Selection | Type | Use Case | Pros | Cons | |------|----------|------|------| | **rust** | Performance-critical, CPU-intensive tasks | High performance, memory safety | Requires Rust toolchain, compilation | | **python** | Rapid development, glue code, existing libraries | Fast iteration, rich ecosystem | Slower execution, GIL limitations | ## Naming Convention Derive all identifiers from the `backend_name` argument: | Concept | Rule | Example (`backend_name` = "code verify") | |---------|------|------------------------------------------| | action_name | lowercase, underscores | `code_verify` | | Backend class | PascalCase + `Backend` | `CodeVerifyBackend` | | Python module | `{action_name}.py` | `code_verify.py` | | lifecycle category | same as action_name | `code_verify` | **Rust-specific** (only when `backend_type=rust`): | Concept | Rule | Example | |---------|------|----------| | Rust function | same as action_name | `code_verify` | | Request struct | PascalCase + `Request` | `CodeVerifyRequest` | | Response struct | PascalCase + `Response` | `CodeVerifyResponse` | --- ## 1. Architecture Overview Both backend types follow the same execution flow: ``` agent-sec-cli ──→ security_middleware.invoke("{action_name}", **kwargs) │ ├─ router.get_backend("{action_name}") │ └─ _REGISTRY["{action_name}"] → "security_middleware.backends.{action_name}" │ └─ lazy import → {ActionName}Backend() │ ├─ backend.execute(ctx, **kwargs) → ActionResult │ │ │ ├─ [Rust] from agent_sec_cli._native import {action_name} │ │ {action_name}(json_in) → json_out │ │ │ └─ [Python] import {module_path} │ module.function(**kwargs) → result │ └─ lifecycle.post_action() → SecurityEvent → JSONL ``` **Key contract**: Every backend is a Python class with an `execute(ctx, **kwargs) → ActionResult` method. The implementation language (Rust/Python) is an **implementation detail** — the middleware never calls Rust or module functions directly. --- ## 2. Create the Python Backend Wrapper The Python backend wrapper is the **unified interface** that the middleware calls. It delegates to either Rust or Python implementation based on `backend_type`. ### 2.1 Choose Template - **For `backend_type=rust`**: Use `templates/rust_backend.py` - **For `backend_type=python`**: Use `templates/python_backend.py` ### 2.2 Create Backend File Create `agent-sec-cli/src/agent_sec_cli/security_middleware/backends/{action_name}.py` Copy the appropriate template and replace placeholders: - `{backend_name}` → actual backend name (e.g., "code_verify") - `{BackendName}` → PascalCase class name (e.g., "CodeVerify") - `{action_name}` → action name for Rust calls (e.g., "code_verify") - `{module_path}` → Python module path (only for python type, e.g., "agent_sec_cli.code_verify.verifier") **Convention**: Class name = PascalCase of module name + `Backend`. > **IMPORTANT — `stdout` / `error` contract**: The CLI (`agent-sec-cli`) only > prints `result.stdout` and `result.error`. If a backend returns an `ActionResult` > with both `stdout` and `error` empty, the CLI produces **no output at all**. > Every `ActionResult` **must** populate at least one of: > > | Field | When to set | > |-------|-------------| > | `stdout` | Always on success — human-readable text for the terminal | > | `error` | Always on failure — written to stderr by the CLI | > > A helper like `_format_stdout()` keeps formatting in one place and makes it > easy to test independently. --- ## 3. Register Backend in Router and Lifecycle ### 3.1 Register in Router Edit `agent-sec-cli/src/agent_sec_cli/security_middleware/router.py` — add to `_REGISTRY`: ```python _REGISTRY: Dict[str, str] = { # ... existing entries ... "{action_name}": "agent_sec_cli.security_middleware.backends.{action_name}", } ``` ### 3.2 Add Lifecycle Category Mapping Edit `agent-sec-cli/src/agent_sec_cli/security_middleware/lifecycle.py` — add to `_ACTION_CATEGORY`: ```python _ACTION_CATEGORY: Dict[str, str] = { # ... existing entries ... "{action_name}": "{action_name}", } ``` ### 3.3 Add CLI Entry Point Edit `src/agent_sec_cli/cli.py` — add a new `@app.command()` function: ```python # {action_name} subcommand @app.command() def {action_name}( param1: str = typer.Option("", "--param1", help="Parameter 1"), # Add more arguments as needed for the backend ): """{ActionName} description.""" result = invoke("{action_name}", param1=param1) if result.stdout: typer.echo(result.stdout) if result.error: typer.echo(result.error, err=True) raise typer.Exit(code=result.exit_code) ``` Now callable as: ```bash agent-sec-cli {action_name} --param1 value ``` --- ## 4. Rust-Specific Steps (backend_type=rust) > Skip this section if `backend_type=python`. > **Sub-skill available**: For complex Rust modules (multiple files, shared types, > or workspace-scale projects), use the **`add-rust-module`** sub-skill at > `sub-skills/add-rust-module.md`. It covers single-file modules, directory modules, > and Cargo workspace layouts. > > The steps below cover the **simple inline case** (adding a function directly to > `src/lib.rs`). For anything beyond a single function, delegate to the sub-skill: > > ``` > add-rust-module module_name="{action_name}" functions="{action_name}" > ``` ### 4.1 Add Rust Function to lib.rs Edit `agent-sec-cli/src/lib.rs` — add your Rust function above the `#[pymodule]` block: ```rust // --------------------------------------------------------------------------- // {action_name} // --------------------------------------------------------------------------- #[derive(Deserialize)] struct {ActionName}Request { // Add domain-specific fields here } #[derive(Serialize)] struct {ActionName}Response { // Add domain-specific output fields here } /// Pure Rust logic — no Python API calls. fn do_{action_name}(req: &{ActionName}Request) -> Result<{ActionName}Response, String> { // Implement domain logic here todo!("implement {action_name} logic") } #[pyfunction] fn {action_name}(py: Python<'_>, request_json: &str) -> PyResult<String> { let req: {ActionName}Request = serde_json::from_str(request_json) .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>( format!("Invalid JSON: {e}") ))?; py.allow_threads(|| { let resp = do_{action_name}(&req) .map_err(|e| PyErr::new::<pyo3::exceptions::PyValueError, _>(e))?; serde_json::to_string(&resp) .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>( format!("Serialization failed: {e}") )) }) } ``` ### 4.2 Register in #[pymodule] Add this line inside the `_native` pymodule function in `src/lib.rs`: ```rust m.add_function(wrap_pyfunction!({action_name}, m)?)?; ``` ### 4.3 Update Python Backend Wrapper Edit `agent-sec-cli/src/agent_sec_cli/security_middleware/backends/{action_name}.py`: ```python from agent_sec_cli._native import {action_name} as rust_{action_name} class {BackendName}Backend: def execute(self, ctx, **kwargs) -> ActionResult: try: req = json.dumps(kwargs) resp_json = rust_{action_name}(req) resp = json.loads(resp_json) return ActionResult( success=True, data=resp, stdout=self._format_stdout(resp), ) except Exception as exc: return ActionResult(success=False, error=f"Rust error: {exc}", exit_code=1) ``` **Key changes**: - No `RUST_AVAILABLE` check needed (Rust code is always available) - Import directly from `agent_sec_cli._native` - No Python fallback (unless you intentionally keep it) ### 4.4 Build and Test #### 4.4.1 Rebuild with maturin ```bash cd agent-sec-cli uv run maturin develop --release ``` #### 4.4.2 Test from Python ```python from agent_sec_cli._native import {action_name} import json req = json.dumps({"param": "value"}) resp = {action_name}(req) print(json.loads(resp)) ``` #### 4.4.3 Run Rust Tests ```bash cd agent-sec-cli cargo test ``` ### 4.5 Add Dependencies (if needed) If your Rust function needs additional crates (e.g., `serde`, `serde_json`), edit `agent-sec-cli/Cargo.toml`: ```toml [dependencies] pyo3 = { version = "0.20", features = ["extension-module"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" ``` ### 4.6 Complex Rust Modules If the Rust logic is too large for a single function in `lib.rs`, use the **`add-rust-module`** sub-skill to create a dedicated module: ``` add-rust-module module_name="{action_name}" functions="{action_name}" complex="true" ``` This will: 1. Create `src/{action_name}/mod.rs` with proper sub-module layout 2. Wire `mod {action_name};` into `src/lib.rs`
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기