# Advanced Concepts: Container Tools, Scope Chain, Budgets & Safety (v3.6.0) > **Milestone:** v3.6.0 — M7: Advanced Concepts & Deferred Features > **Parent:** [Advanced Concepts Overview](index.md) --- ## Container Tool Execution v3.6.0 adds first-class support for executing tools inside containers, building on the container resource types introduced in ADR-039. ### Overview Container tool execution allows actors to run tools in isolated container environments rather than directly on the host. This provides: - **Stronger isolation** — tool side effects are contained within the container - **Reproducible environments** — tools run in a known, versioned environment - **Language-agnostic tools** — tools can be written in any language supported by the container - **Parallel execution** — multiple containers can run simultaneously for independent tool calls ### Container Tool Configuration Tools declare their container requirements in their YAML definition: ```yaml name: my-org/python-linter type: container-tool image: "python:3.12-slim" command: ["python", "-m", "pylint"] mounts: - source: "{{resource.git_dir.path}}" target: "/workspace" readonly: true environment: PYTHONPATH: "/workspace/src" timeout: 60 ``` ### Execution Model Container tools follow the same `ToolRuntime` interface as host tools. The `ContainerToolExecutor` handles: 1. **Image resolution** — pulls the image if not cached locally 2. **Mount binding** — maps resource paths to container mount points 3. **Execution** — runs the container with the specified command and arguments 4. **Output capture** — streams stdout/stderr back to the `ToolResult` 5. **Cleanup** — removes the container after execution (configurable) ### Devcontainer Integration When a project has a `.devcontainer/devcontainer.json`, CleverAgents can use the devcontainer as the execution environment for all tools in that project. This is configured via the `devcontainer-instance` resource type (ADR-043): ```yaml resources: - name: dev_env type: devcontainer-instance devcontainer_path: ".devcontainer/devcontainer.json" use_for_tools: true ``` --- ## Pluggable Scope Chain Resolution Extensions The scope chain resolution system determines which projects, plans, and resources are in scope for a given actor invocation. v3.6.0 makes this system extensible via a plugin interface. ### Scope Chain Resolution Protocol The `ScopeChainResolver` interface defines a single method: ```python class ScopeChainResolver(Protocol): def resolve( self, base_scope: Scope, context: ResolutionContext, ) -> Scope: """ Extend or modify the base scope based on the resolution context. Args: base_scope: The scope as determined by the persona and explicit @ references. context: The current resolution context (session, plan, actor, prompt). Returns: The resolved scope, which may add, remove, or reorder items from base_scope. """ ... ``` ### Built-in Resolvers | Resolver | Description | |----------|-------------| | `PersonaScopeResolver` | Adds persona-scoped projects and plans (always active) | | `ReferenceResolver` | Adds explicitly `@`-referenced resources (always active) | | `DependencyGraphResolver` | Automatically includes resources that are dependencies of in-scope resources | | `RecentlyModifiedResolver` | Adds recently modified files from in-scope projects | | `TestCoverageResolver` | Adds test files that cover in-scope source files | ### Custom Resolver Registration Custom resolvers are registered via the plugin system: ```python from cleveragents.scope import ScopeChainResolver, register_resolver @register_resolver(name="my-org/git-blame-resolver", priority=50) class GitBlameResolver: def resolve(self, base_scope, context): # Add files recently modified by the current git user ... ``` --- ## Cost and Session Budgets v3.6.0 introduces comprehensive cost tracking and budget enforcement across sessions and plans. ### Cost Tracking Every LLM invocation is tracked with: - **Input tokens** and **output tokens** (provider-reported) - **Cost in USD** (computed from provider pricing tables, updated monthly) - **Model used** (for multi-provider fallback chains) - **Session ID** and **plan ID** for attribution Cost data is stored in the SQLite database and queryable via: ```bash agents session cost # Total cost for current session agents session cost --all # All sessions with costs agents plan cost # Cost breakdown for a specific plan agents config get billing.total_spent # Lifetime total ``` ### Budget Configuration Budgets are configured at multiple levels (plan > action > project > global): ```toml [billing] max_cost_per_session = 5.00 # USD; hard limit per session max_cost_per_plan = 2.00 # USD; hard limit per plan max_total_cost = 100.00 # USD; lifetime hard limit warn_at_percent = 80 # Warn when 80% of any budget is consumed ``` These settings correspond to the `SafetyProfile` fields defined in ADR-041: | Config Key | SafetyProfile Field | |-----------|-------------------| | `max_cost_per_plan` | `SafetyProfile.max_cost_per_plan` | | `max_total_cost` | `SafetyProfile.max_total_cost` | ### Budget Enforcement When a budget limit is reached: 1. The current LLM invocation is **not** started (pre-flight check) 2. A `BudgetExceededError` is raised with the budget type, limit, and current spend 3. The plan transitions to `PAUSED` state with `pause_reason = "budget_exceeded"` 4. The user is notified via the CLI output or TUI notification system 5. The user can increase the budget via `agents config set billing.max_cost_per_plan ` and resume the plan with `agents plan resume ` --- ## Safety Profiles Safety profiles (ADR-041) provide fine-grained control over what actions an actor is permitted to take. v3.6.0 completes the safety profile implementation with full enforcement in the plan lifecycle. ### SafetyProfile Fields | Field | Type | Default | Description | |-------|------|---------|-------------| | `require_sandbox` | `bool` | `True` | Require sandbox isolation for all file writes | | `require_checkpoints` | `bool` | `True` | Require checkpoints before destructive operations | | `allow_unsafe_tools` | `bool` | `False` | Allow tools marked as `unsafe: true` | | `require_human_approval` | `bool` | `False` | Require human approval before each action step | | `allowed_skill_categories` | `list[str]` | `[]` (all) | Restrict to specific skill categories | | `max_cost_per_plan` | `float or None` | `None` | Maximum cost per plan in USD | | `max_total_cost` | `float or None` | `None` | Maximum lifetime cost in USD | | `max_retries_per_step` | `int` | `3` | Maximum retries per action step (0-100) | ### Built-in Safety Profiles v3.6.0 ships with named safety profiles that can be referenced by name: | Profile | Description | |---------|-------------| | `strict` | All safety flags enabled; no unsafe tools; human approval required | | `standard` | Sandbox and checkpoints required; unsafe tools blocked; no human approval | | `permissive` | Sandbox required; checkpoints optional; unsafe tools allowed | | `read-only` | No file writes permitted; all tools restricted to read operations | | `cost-capped-1usd` | Standard safety + $1.00 per-plan cost cap | | `cost-capped-5usd` | Standard safety + $5.00 per-plan cost cap | ### Applying Safety Profiles Safety profiles can be applied at multiple levels: ```bash # Global default agents config set safety.profile strict # Per-project agents project set-safety my-project --profile standard # Per-plan (at creation time) agents plan use my-action --safety-profile permissive ``` ```yaml # action.yaml name: my-action safety_profile: require_sandbox: true allow_unsafe_tools: false max_cost_per_plan: 2.00 ``` --- ## Related ADRs | ADR | Title | Relevance | |-----|-------|-----------| | [ADR-039](../adr/ADR-039-container-resource-types.md) | Container Resource Types | Container tool execution | | [ADR-041](../adr/ADR-041-safety-profile-extraction.md) | Safety Profile Extraction | Safety profiles and cost budgets | | [ADR-043](../adr/ADR-043-devcontainer-integration.md) | Devcontainer Integration | Devcontainer tool execution | --- *Documentation for v3.6.0 — IN PROGRESS. Features described here reflect the planned scope as of 2026-04-15. Some features may be adjusted as implementation progresses.* *Generated by [AUTO-DOCS-5] — CleverAgents Documentation Bot*