Commit Graph

890 Commits

Author SHA1 Message Date
hamza.khyari 5d0e739e43 fix(acms): wire ACMS indexing pipeline into CLI so ContextTierService is populated during plan execution
ContextTierService started empty on every CLI invocation, so the LLM
received zero file context during plan execution (bug #1028).

- Add context_tier_hydrator.py: reads files from linked project resources
  (via git ls-files or os.walk) and stores them as TieredFragment objects
  in the tier service.  Respects max file size (256 KB), total budget
  (10 MB), binary exclusion, and .git/node_modules/__pycache__ skipping.
- Wire hydration into LLMExecuteActor.execute() via lazy import (avoids
  M1 E2E regression from top-level import).
- Inject tier_service, project_repository, resource_registry into
  LLMExecuteActor from the DI container in _get_plan_executor().
- Add tier_service property to ExecutePhaseContextAssembler.
- Suppress exc_info traceback rendering in context warnings to prevent
  false-positive crash detection in M1 E2E tests.
- Add sandbox file-writing support in plan apply (path traversal guards,
  protected directory skipping).
- Add 6 Behave scenarios for context tier hydration.

Closes #1028
2026-04-09 13:00:47 +00:00
hurui200320 ee2024046f fix(plan): upsert action arguments during plan use to avoid UNIQUE constraint violation (#4197)
## Summary

`agents plan use` crashed with `sqlite3.IntegrityError: UNIQUE constraint failed: action_arguments.action_name, action_arguments.name` when the action had arguments already registered via `action create`. The root cause was `ActionRepository.update()` using SQLAlchemy's relationship `.clear()` + `.append()` pattern, which deferred the DELETE and processed the INSERT first — triggering a UNIQUE constraint violation when the same `(action_name, name)` pair was being re-inserted.

## Approach

Replace the `.clear()` + `.append()` pattern with explicit bulk `sa_delete()` + `session.flush()` before re-inserting child rows for both `action_arguments` and `action_invariants`. After the flush, expire the relationship collections with `session.expire(row, ["arguments_rel", "invariants_rel"])` so SQLAlchemy reloads from the now-empty database state before appending replacements. This avoids stale identity map references and guarantees the DELETE is committed before any INSERT.

## Key Changes

### Bug fix (`src/cleveragents/infrastructure/database/repositories.py`)
- `ActionRepository.update()` now uses `sa_delete(ActionArgumentModel)` and `sa_delete(ActionInvariantModel)` with `synchronize_session=False`, followed by `session.flush()`, before re-inserting child rows.
- Targeted `session.expire(row, ["arguments_rel", "invariants_rel"])` replaces the removed `.clear()` calls to force collection reload.

### Schema parity (`src/cleveragents/infrastructure/database/models.py`)
- Added `UniqueConstraint("action_name", "position")` to `ActionInvariantModel`.
- Added `UniqueConstraint("action_name", "name")`, `CheckConstraint` for `arg_type`, and `CheckConstraint` for `requirement` to `ActionArgumentModel`.

### Alembic migration (`alembic/versions/a5_006_action_invariants_unique_constraint.py`)
- New migration adds all four constraints to both `action_invariants` and `action_arguments` tables.
- Includes deduplication guards and data normalization so the upgrade succeeds on existing databases with invalid or duplicate rows.
- Uses `batch_alter_table` for SQLite compatibility.

### Tests
- **Behave** (`features/plan_use_action_args_integrity.feature`): 6 scenarios covering the core bug path, zero-argument regression, multiple arguments, reusable action double-use, non-reusable action archival with invariants, and direct repository update.
- **Robot** (`robot/plan_use_action_args_integrity.robot`): Integration test mirroring the Behave scenarios via a helper script.
- **Shared factory** (`features/mocks/test_uow_factory.py`): Extracted `build_test_uow()` from both test suites into a single shared module to eliminate duplication (DRY).

### Minor
- Updated `src/cleveragents/domain/repositories/__init__.py` docstring from table format to bullet list (conflict resolution from rebase).

Closes #4174

Reviewed-on: cleveragents/cleveragents-core#4197
Reviewed-by: HAL 9000 <HAL9000@cleverthis.com>
Co-authored-by: Rui Hu <rui.hu@cleverthis.com>
Co-committed-by: Rui Hu <rui.hu@cleverthis.com>
2026-04-09 06:11:39 +00:00
freemo 8ea00f5185 fix: restore CI quality tests to passing state (#4175)
Co-authored-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Co-committed-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
2026-04-08 11:02:14 +00:00
freemo 225eab25b1 fix(cli): change agents validation attach extra args to use --key value named option format (#3837)
Co-authored-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Co-committed-by: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
2026-04-06 07:55:09 +00:00
freemo 36fb867830 fix(acms): invoke SkeletonCompressor in ContextAssembler.assemble() to propagate skeleton context to child plans
Reviewed and APPROVED. Critical bug fix. Closes #3563.
2026-04-05 21:31:14 +00:00
freemo ca3399e177 fix(acms): invoke SkeletonCompressor in ContextAssembler.assemble() to propagate skeleton context to child plans
Added skeleton_fragments: tuple[ContextFragment, ...] field to ContextPayload in context_fragment.py
- Enables carrying compressed skeleton fragments along with normal context.

Extended ACMSPipeline.assemble() in acms_service.py
- Introduced skeleton_ratio: float = 0.15 (default matching spec) and parent_fragments: tuple[ContextFragment, ...] | None = None parameters.
- These same parameters are also added to ContextAssemblyPipeline.assemble() in acms_pipeline.py for consistency.

Skeleton compression integration
- In Phase 3 of both assemble() methods, computed skeleton_budget = int(budget.available_tokens * skeleton_ratio) and invoked self._skeleton_compressor.compress(parent_fragments, skeleton_budget).
- Compressed skeleton fragments are included in the returned ContextPayload.skeleton_fragments, enabling propagation of skeleton context to child plans.

Tests and behavior coverage
- Added a TDD issue-capture Behave scenario (@tdd_issue @tdd_issue_3563) to demonstrate the fix.
- Added four Behave unit test scenarios asserting: compressor invocation, correct arguments, skeleton presence in output, and skeleton_ratio budget enforcement.
- Added a Robot Framework integration test: parent plan accumulates context → child plan spawned → child plan context contains non-empty skeleton.
- Added skeleton-context-inheritance command to helper_acms_pipeline.py to support testing and manual verification.

Key design decisions
- skeleton_ratio defaults to 0.15 to align with the spec's --skeleton-ratio default.
- parent_fragments is None by default to maintain backward compatibility (no skeleton compression when no parent context).
- skeleton_budget is computed as skeleton_budget = int(budget.available_tokens * skeleton_ratio), deriving the skeleton budget from the total token budget.
- Both ACMSPipeline and ContextAssemblyPipeline are fixed to maintain consistency across the codepath.

ISSUES CLOSED: #3563
2026-04-05 21:26:33 +00:00
freemo 201868afd8 fix(cli): route 'agents actor add' through ActorRegistry YAML-first path with all CLI flags preserved
Reviewed and APPROVED. All blocking issues addressed. Closes #3426.
2026-04-05 21:20:20 +00:00
freemo 99b4067ec2 fix(cli): extend agents diagnostics to check all 9 supported providers
Reviewed and APPROVED. All blocking issues addressed. Closes #3422.
2026-04-05 21:19:43 +00:00
freemo 62ded31c24 fix(cli): route 'agents actor add' through ActorRegistry.add() YAML-first path
Route the 'agents actor add' CLI command through ActorRegistry.add() instead
of the legacy registry.upsert_actor() path. This ensures the original YAML
text, schema_version, and compiled_metadata are preserved in the database.

Changes:
- src/cleveragents/cli/commands/actor.py: Add _load_config_text() helper that
  returns both raw text and parsed dict. Refactor add() to call registry.add()
  with the raw yaml_text and update=update_existing flag when a registry is
  available. The service fallback path (no registry) is unchanged.
- features/steps/actor_cli_steps.py: Update add command step definitions to
  mock registry.add() instead of registry.upsert_actor(). Update 'the actor
  add should pass the loaded config' assertion to verify registry.add() is
  called with a non-empty yaml_text string.
- features/steps/actor_cli_yaml_steps.py: Update add command steps to mock
  registry.add() instead of registry.upsert_actor().
- features/steps/actor_add_rich_output_steps.py: Update add command steps to
  mock registry.add() instead of registry.upsert_actor().
- robot/helper_actor_add_rich_output.py: Update helper to mock registry.add()
  instead of registry.upsert_actor().
- features/actor_add_yaml_first_path.feature: New Behave feature verifying
  the YAML-first persistence path is used by actor add.
- features/steps/actor_add_yaml_first_path_steps.py: Step definitions for
  the new YAML-first path feature.
- robot/actor_add_yaml_first_path.robot: New Robot integration tests verifying
  yaml_text is preserved and upsert_actor is not called.
- robot/helper_actor_add_yaml_first_path.py: Helper script for Robot tests.

Fixes #3426

ISSUES CLOSED: #3426
2026-04-05 21:19:40 +00:00
freemo 234d71560d fix(executor): implement automatic per-tool-write and event-based checkpoint triggers
Reviewed and APPROVED. All blocking issues addressed. Closes #3439.
2026-04-05 21:19:18 +00:00
freemo 461adcdb2a fix(cli): correct automation-profile list output structure and rich table rendering
Reviewed and APPROVED. Closes #2064.
2026-04-05 21:16:24 +00:00
freemo fa0dd3594f fix(mcp): correct MCPToolResult.data type annotation for MCP 1.4.0 content list format
Reviewed and APPROVED. Closes #2743.
2026-04-05 21:16:21 +00:00
freemo fdb3787fe3 feat(cli): add --container-id flag to agents resource add for container-instance
Reviewed and APPROVED. Closes #2598.
2026-04-05 21:16:18 +00:00
freemo 97a90e59c4 fix(domain): add missing execute hook to ToolLifecycle model to satisfy spec four-stage lifecycle
Reviewed and APPROVED. Closes #2820.
2026-04-05 21:16:05 +00:00
freemo 098955693d fix(tool-registry): reject plain Tools in attach_validation type-discriminator check
Reviewed and APPROVED. Closes #2826.
2026-04-05 21:14:58 +00:00
freemo ce4dbdb53f fix(domain): add repository protocol interfaces to domain layer
Reviewed and APPROVED. Closes #2873.
2026-04-05 21:14:56 +00:00
freemo 181ec4d2c2 fix(concurrency): protect CostTracker._daily_costs with a threading.Lock
Reviewed and APPROVED. Closes #1919.
2026-04-05 21:14:08 +00:00
freemo 4b03d69770 refactor(tests): improve data variation in existing tests using factory and fixture system
Reviewed and APPROVED. Closes #2772.
2026-04-05 21:14:05 +00:00
freemo b565d86847 fix(cli): raise on subcommand registration failure instead of silently returning
Reviewed and APPROVED. Closes #2604.
2026-04-05 21:13:58 +00:00
freemo c92a65bc92 fix(resource): use namespace column instead of name heuristic in db_to_spec() for built_in field
Reviewed and APPROVED. Closes #3013.
2026-04-05 21:13:56 +00:00
freemo c3b2f59772 fix(sandbox): remove type: ignore in SandboxManager strategy assignment
Reviewed and APPROVED. Closes #2828.
2026-04-05 21:13:07 +00:00
freemo 78e146d169 fix(executor): implement automatic per-tool-write and event-based checkpoint triggers
Implements all four automatic checkpoint triggers defined in the specification
for the Execute phase of the plan lifecycle:

- before_tool_execute: Checkpoint created before any tool with writes=True runs
- after_tool_execute: Checkpoint created after a write tool completes successfully
- on_subplan_spawn: Checkpoint created immediately after a child plan is spawned
- on_error: Checkpoint created after any unrecoverable error in the Execute phase

Changes:
- tool/runner.py: Added optional CheckpointService and auto_checkpoint_triggers
  parameters to ToolRunner. Checkpoint hooks fire around write-tool execution
  when a CheckpointService is wired. Exported DEFAULT_AUTO_TRIGGERS as a public
  constant (single source of truth). Made is_trigger_active() public so callers
  can query the active trigger set without accessing private attributes.
- application/services/subplan_execution_service.py: Added optional
  CheckpointService, auto_checkpoint_triggers, and parent_plan_id parameters.
  on_subplan_spawn checkpoint fires in _execute_one_with_retry before the
  first execution attempt. Now imports DEFAULT_AUTO_TRIGGERS from runner.py
  (DRY fix).
- application/services/plan_executor.py: Added _is_auto_trigger_active() helper
  and on_error checkpoint hooks in both _run_execute_with_stub() and
  _run_execute_with_runtime() error paths. Delegates to
  ToolRunner.is_trigger_active() instead of accessing private attributes
  (module boundary fix).
- application/services/config_service.py: Registered new config key
  core.checkpoints.auto_create_on (default: all four triggers enabled) with
  env var CLEVERAGENTS_CHECKPOINT_AUTO_CREATE_ON.
- application/services/llm_actors.py: Replaced Any type for lifecycle_service
  with PlanLifecycleProtocol (typed Protocol) and tool_runner with ToolRunner
  type annotation. Eliminates Any usage for injected dependencies.

Tests:
- features/checkpoint_auto_triggers.feature: 15 Behave scenarios covering all
  four triggers, disable-trigger behavior, no-checkpoint-service fallback, and
  config key registration.
- features/steps/checkpoint_auto_triggers_tool_steps.py: Step definitions for
  ToolRunner and config service scenarios (split from original 519-line file).
- features/steps/checkpoint_auto_triggers_executor_steps.py: Step definitions
  for SubplanExecutionService and PlanExecutor scenarios (split from original).

Closes #3439

ISSUES CLOSED: #3439
2026-04-05 21:13:07 +00:00
freemo a3eb9ea9d1 fix(cli): add missing _log.debug call to session export/import/tell DatabaseError handlers
Reviewed and APPROVED. Closes #2788.
2026-04-05 21:13:04 +00:00
freemo 188ea031eb fix(resources): register fs-mount built-in resource type at startup
Reviewed and APPROVED. Closes #2911.
2026-04-05 21:13:02 +00:00
freemo b9c3ccee37 fix(robot): correct dedent logic for try...except...finally in indentation_library
Reviewed and APPROVED. Closes #2845.
2026-04-05 21:13:01 +00:00
freemo 8f43352723 fix(resource-type): require letter-start for namespace/name in _NAMESPACED_RE
Reviewed and APPROVED. Closes #2983.
2026-04-05 21:12:17 +00:00
freemo 3d7f213527 fix(tdd): replace non-standard @tdd_bug tags with @tdd_issue per CONTRIBUTING.md
Reviewed and APPROVED. Closes #2779.
2026-04-05 21:12:14 +00:00
freemo 54285e0f33 fix(cli): correct session show rich output Session Summary panel field labels and fields
Reviewed and APPROVED. Closes #3040.
2026-04-05 21:12:13 +00:00
freemo 0b8152b9d0 fix(tui): show command descriptions in SlashCommandOverlay alongside command names
Reviewed and APPROVED. Closes #3437.
2026-04-05 21:12:09 +00:00
freemo b6959aeffe fix(actors): enforce --update flag in agents actor add to prevent silent overwrites
Reviewed and APPROVED. Closes #2609.
2026-04-05 21:11:55 +00:00
freemo c8b66c8294 fix(config): align Settings and alembic/env.py database_url defaults to spec-required ~/.cleveragents/cleveragents.db
Reviewed and APPROVED. Closes #2871.
2026-04-05 21:11:53 +00:00
freemo 6be538bd5c fix(resources): add overlay to ResourceTypeConfigSchema sandbox strategy validation
Reviewed and APPROVED. Closes #2827.
2026-04-05 21:11:50 +00:00
freemo 1e3390f228 fix(a2a): update A2aVersionNegotiator to support JSON-RPC 2.0
Reviewed and APPROVED. Closes #2747.
2026-04-05 21:11:40 +00:00
freemo 31b8294f2d fix(tool): wire 6-level execution environment precedence chain in ToolRunner
Reviewed and APPROVED. Closes #2592.
2026-04-05 21:11:38 +00:00
freemo 2a541bb1e1 fix(cli): add Name and Updated columns to agents plan list table output
Reviewed and APPROVED. Closes #2611.
2026-04-05 21:11:36 +00:00
freemo 4aaf865420 fix(acms): implement real retrieval logic in all 6 spec-required context strategies
Reviewed and APPROVED. Priority/Critical fix. Closes #3500.
2026-04-05 21:11:34 +00:00
freemo 869777bb86 fix(tui): add plain text format support to session export command
Reviewed and APPROVED. Closes #3036.
2026-04-05 21:10:16 +00:00
freemo ef557a31a9 fix(a2a): change A2aErrorDetail.code to int and map error constants to JSON-RPC 2.0 integer codes
Reviewed and APPROVED. Closes #2746.
2026-04-05 21:10:14 +00:00
freemo e749513704 fix(persistence): persist reversion_count, last_completed_step, and last_checkpoint_id on LifecyclePlanModel
Reviewed and APPROVED. Closes #2864.
2026-04-05 21:10:10 +00:00
freemo 660a194012 fix(ci): update nightly workflow coverage minimum to 97% per project requirements
Reviewed and APPROVED. Closes #2773.
2026-04-05 21:09:50 +00:00
freemo 86999ea959 fix(config): add server_url, server_token, format, and default_estimation_actor fields to Settings
Reviewed and APPROVED. Closes #2870.
2026-04-05 21:09:46 +00:00
freemo 920faa0dd8 fix(a2a): add A2A Python SDK as project dependency
Reviewed and APPROVED. Closes #2858.
2026-04-05 21:09:44 +00:00
freemo f4233fb3bd fix(config): correct Settings.data_dir default from Path("data") to Path.home() / ".cleveragents"
Reviewed and APPROVED. Closes #2851.
2026-04-05 21:09:36 +00:00
freemo 539f500abe fix(skills): add lowercase-only namespace/name pattern validation to SkillConfigSchema and ActionConfigSchema
Reviewed and APPROVED. Closes #3029.
2026-04-05 21:09:24 +00:00
freemo 2e2202e52f fix(tests): add missing Behave feature file for coverage threshold config
Reviewed and APPROVED. Closes #2767.
2026-04-05 21:09:17 +00:00
freemo eb4ccc819c fix(cli): add NAME positional argument to agents actor add command per spec
Reviewed and APPROVED. Closes #2905.
2026-04-05 21:09:13 +00:00
freemo e5380eabdf fix(acms): align DEFAULT_SKELETON_RATIO default value with spec
Reviewed and APPROVED.
2026-04-05 21:09:10 +00:00
freemo a145986df6 fix(cli): promote --format to global CLI callback option per spec
Reviewed and APPROVED.
2026-04-05 21:09:07 +00:00
freemo e1fbcf6345 fix(sandbox): use spec-required cleveragents/plan- branch naming in git worktree
Reviewed and APPROVED. Closes #2601.
2026-04-05 21:09:04 +00:00
freemo 5824e7c0aa fix(database): move get_all_for_project call outside loop in LegacyDataMigrator
Reviewed and APPROVED. Closes #3047.
2026-04-05 21:08:47 +00:00