Files
CoreRasurae 0c5b140d29
CI / push-validation (pull_request) Successful in 18s
CI / lint (pull_request) Successful in 26s
CI / helm (pull_request) Successful in 38s
CI / build (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 54s
CI / security (pull_request) Successful in 55s
CI / typecheck (pull_request) Successful in 57s
CI / e2e_tests (pull_request) Successful in 4m48s
CI / unit_tests (pull_request) Successful in 8m5s
CI / integration_tests (pull_request) Successful in 9m23s
CI / docker (pull_request) Successful in 1m23s
CI / coverage (pull_request) Successful in 12m29s
CI / benchmark-regression (push) Failing after 0s
CI / benchmark-publish (push) Failing after 0s
CI / status-check (pull_request) Successful in 1s
CI / push-validation (push) Successful in 12s
CI / helm (push) Successful in 29s
CI / build (push) Successful in 3m23s
CI / lint (push) Successful in 3m38s
CI / quality (push) Successful in 3m40s
CI / security (push) Successful in 4m3s
CI / typecheck (push) Successful in 4m5s
CI / e2e_tests (push) Successful in 6m42s
CI / unit_tests (push) Successful in 10m7s
CI / integration_tests (push) Successful in 10m13s
CI / docker (push) Successful in 1m46s
CI / coverage (push) Successful in 10m58s
CI / status-check (push) Successful in 2s
fix(database): include alembic files in package distribution
Move alembic configuration and migration files from repository root into the
Python package structure to ensure they are included in the wheel distribution.

This fix resolves the FileNotFoundError when running `agents init` in Docker
containers or any environment using the built wheel distribution.

Changes:
- Move alembic/ directory from repo root to
  src/cleveragents/infrastructure/database/migrations/
- Move alembic.ini to the same new location and update script_location setting
- Update MigrationRunner._find_alembic_ini() to search from the new canonical
  location within the package
- Update create_template_db.py to point to the new alembic.ini location
- Update documentation references to reflect new migration file locations
- Create __init__.py for migrations package

- The env.py file is imported when running tests that verify all modules can be
  imported without errors. However, context.config is only available when alembic
  is actually running migrations, not during normal module imports. This caused
  an AttributeError when the test tried to import the migrations.env module.

- Fix by using getattr() with a default value to safely access context.config,
  and guard all code that uses config with None checks. This allows the module
  to be safely imported while still functioning correctly during migrations.

Testing:
- Verified MigrationRunner can locate alembic.ini in new location
- Tested agents init succeeds in creating project with database
- Template database creation works correctly
- All migration tests should pass without changes

Alembic files now follow standard Python packaging conventions, making them
automatically included in wheel distributions without special configuration.

ISSUES CLOSED: #4180
2026-04-17 17:40:00 +00:00

10 KiB

Resource Registry

The Resource Registry manages resource types and resource instances in CleverAgents. Resource types define schemas, sandbox strategies, and handler implementations. Resource instances are registered entries that plans operate on during execution.

Built-in Resource Types

CleverAgents ships with two built-in types, available without registration:

Type Kind Sandbox Strategy Handler
git-checkout physical git_worktree GitCheckoutHandler
fs-directory physical copy_on_write FsDirectoryHandler

Built-in types are registered idempotently at startup via ResourceRegistryService.bootstrap_builtin_types().

Resource Type Fields

Each ResourceTypeSpec defines a resource type schema:

Field Type Description
name str Unique name (built-in: bare, custom: namespace/name)
description str Human-readable description
resource_kind ResourceKind physical or virtual
sandbox_strategy SandboxStrategy Default sandbox isolation strategy
user_addable bool Whether users can register instances of this type
built_in bool Whether this is a built-in type
cli_args list[ResourceTypeArgument] CLI argument definitions for registration
parent_types list[str] Allowed parent type names in the DAG
child_types list[str] Allowed child type names in the DAG
handler str | None Handler ref in module:Class format
capabilities dict[str, bool] read, write, sandbox, checkpoint flags
auto_discovery dict | None Auto-discovery rules (see below)
equivalence dict | None Virtual resource deduplication config

Custom Types

Custom types are defined in YAML and registered via CLI or API:

name: myteam/python-package
description: A Python package directory
resource_kind: physical
sandbox_strategy: copy_on_write
user_addable: true
cli_args:
  - name: path
    type: path
    required: true
    description: Path to the package root
parent_types:
  - git-checkout
child_types:
  - fs-directory

Register with: agents resource type add path/to/type.yaml

Resource Instance Fields

Each Resource represents a registered asset:

Field Type Description
resource_id str (ULID) Unique identifier
name str | None Optional namespaced name
resource_type_name str Type this resource belongs to
classification PhysVirt physical or virtual
description str | None Human-readable description
location str | None Filesystem path (physical resources)
sandbox_strategy SandboxStrategy | None Per-resource sandbox override
content_hash str | None Hash of resource contents for change detection
parents list[str] Parent resource IDs in the DAG
children list[str] Child resource IDs in the DAG
properties dict Type-specific key-value properties
capabilities ResourceCapabilities readable, writable, sandboxable, checkpointable
created_at datetime Registration timestamp
updated_at datetime Last modification timestamp

Registry Service API

Type Operations

Method Description
bootstrap_builtin_types() Register built-in types (idempotent)
register_type(config_path) Register a custom type from YAML
list_types(namespace=) List types, optionally filtered
show_type(name) Get a type by name

Resource Operations

Method Description
register_resource(type_name, name=, location=, ...) Create and register an instance
list_resources(type_name=) List resources, optionally by type
show_resource(name_or_id) Get by namespaced name or ULID

DAG Operations

Method Description
link_child(parent, child) Link a child to a parent
unlink_child(parent, child) Remove a parent-child link
get_children(name_or_id) Get direct children
get_resource_tree(name_or_id, depth=, type_filter=) Recursive tree traversal

For DAG rules, cycle detection, type compatibility, and auto-discovery details, see Resource DAG.

Discovery Behavior

Auto-Discovery

Resource types can define auto-discovery rules that materialize child resources automatically:

auto_discovery:
  enabled: true
  rules:
    - type: fs-directory
      pattern: "*/"
    - type: fs-file
      pattern: "*"

When auto_discover_children(resource_id) is called:

  1. The resource and its type are looked up.
  2. Each discovery rule is evaluated:
    • The child type must exist in the registry.
    • The child type must be compatible with the parent type (per child_types).
  3. New child resources are created with auto_discovered = true.
  4. Links are created in the resource_links table.

Auto-discovery is triggered:

  • When a resource is first registered
  • When resource contents change
  • On demand via CLI (agents resource discover)

Local-Mode Discovery

In local mode (the default), discovery operates against the local filesystem. The registry creates placeholder resource entries based on discovery rules; actual file enumeration is delegated to resource handlers at sandbox creation time.

Database Schema

resource_types Table

Column Type Description
name String(128) Primary key
namespace String(64) Namespace (or builtin)
description Text Human-readable description
resource_kind String(16) physical or virtual
sandbox_strategy String(32) Default sandbox strategy
user_addable Boolean User registration allowed
built_in Boolean Built-in type flag
handler String(256) Handler module:Class ref
args_schema_json Text CLI args JSON
allowed_parent_types_json Text Allowed parent types JSON
allowed_child_types_json Text Allowed child types JSON
auto_discover_json Text Auto-discovery config JSON
capabilities_json Text Capabilities JSON
equivalence_json Text Equivalence config JSON
source String(256) Registration source
created_at String(30) ISO-8601 timestamp
updated_at String(30) ISO-8601 timestamp

resources Table

Column Type Description
resource_id String(26) ULID primary key
namespaced_name String(256) Optional namespaced name (unique)
namespace String(64) Namespace extracted from name
type_name String(128) FK to resource_types.name
resource_kind String(16) physical or virtual
location Text Filesystem path
description Text Human-readable description
read_only Boolean Read-only flag
auto_discovered Boolean Created by auto-discovery
sandbox_strategy String(32) Per-resource sandbox override
content_hash String(128) Content hash for change detection
properties_json Text Type-specific properties JSON
metadata_json Text Additional metadata JSON
created_at String(30) ISO-8601 timestamp
updated_at String(30) ISO-8601 timestamp

See Resource DAG for link table schema.

Source

  • Domain models: src/cleveragents/domain/models/core/resource.py, resource_type.py
  • Service: src/cleveragents/application/services/resource_registry_service.py
  • Migration: src/cleveragents/infrastructure/database/migrations/versions/b1_001_resource_registry_tables.py
  • CLI: src/cleveragents/cli/commands/resource.py
  • Specification: docs/specification.md — Resource Registry sections