Skip to content

Replace single flow.yaml with distributed YAML configuration system#24035

Draft
lucia-sb wants to merge 22 commits into
loa/task-contextfrom
lucia-sb/ai-6835/dist-config
Draft

Replace single flow.yaml with distributed YAML configuration system#24035
lucia-sb wants to merge 22 commits into
loa/task-contextfrom
lucia-sb/ai-6835/dist-config

Conversation

@lucia-sb

Copy link
Copy Markdown
Contributor

What does this PR do?

Replaces the single flow.yaml file model with a distributed YAML configuration system. Typed resource objects (agents, phases, flows) can now be spread across multiple YAML files in any directory and are assembled at runtime by a new ConfigurationEngine.

Motivation

The monolithic flow.yaml approach doesn't scale — as the number of flows, agents, and phases grows, a single file becomes hard to maintain and prevents reuse across flows. A Terraform-style distributed model lets each resource live in its own file, be shared across flows, and be overridden by user-supplied directories.

Key changes:

  • New ddev/src/ddev/ai/config/ package with models.py (resource types + envelopes) and engine.py (ConfigurationEngine with multi-directory scanning and build_flow validation)
  • AgentConfig and PhaseConfig moved from ddev.ai.phases.config to ddev.ai.config.models; FlowConfig replaced by distributed envelope model
  • config_dir removed from FlowContext; paths are pre-resolved to absolute by build_flow() before reaching phases
  • PhaseOrchestrator updated to accept ConfigurationEngine + flow_name instead of a single file path
  • src/ddev/ai/flows added to wheel artifacts so bundled flow definitions ship with the package
  • 1230 tests passing

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Add qa/required if this PR needs QA validation, or qa/skip-qa if it does not. Exactly one of the two is required.
  • If you need to backport this PR to another branch, you can add the backport/<branch-name> label to the PR and it will automatically open a backport PR once this one is merged

@lucia-sb lucia-sb requested a review from a team as a code owner June 12, 2026 12:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b294401a27

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +49 to +53
discover_and_register_phases(
self._phase_registry,
Path(__file__).parent.parent / "phases",
"ddev.ai.phases",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Register flow-local phase classes before validation

When a distributed flow references a custom phase class, this initialization now only registers classes from ddev.ai.phases; it no longer scans the flow's own phases/ directory as the old orchestrator did. The existing OpenMetrics custom phase lives at ddev/src/ddev/ai/flows/openmetrics/phases/inspect_endpoint.py, so a flow entry with class: InspectEndpointPhase reaches self._phase_registry.get(...) and fails as an unknown phase before the pipeline can start.

Useful? React with 👍 / 👎.

lucia-sb and others added 9 commits June 12, 2026 14:35
…wConfig, envelopes)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…igurationEngine

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…g from phases/config; update all import sites

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…trator pending Task 5

- phases/config.py: rename _detect_cycles -> detect_cycles (public API)
- config/engine.py: update call site to detect_cycles
- tests/ai/config/test_engine.py: add missing engine tests
- runtime/orchestrator.py: stub on_initialize with FlowConfigError pending Task 5 migration; remove unused imports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d absolute paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lucia-sb lucia-sb force-pushed the lucia-sb/ai-6835/dist-config branch from b294401 to 0bb6525 Compare June 12, 2026 12:42
@lucia-sb lucia-sb marked this pull request as draft June 12, 2026 12:44
@datadog-prod-us1-3

This comment has been minimized.

@lucia-sb lucia-sb added the qa/skip-qa Automatically skip this PR for the next QA label Jun 12, 2026
lucia-sb and others added 2 commits June 12, 2026 15:18
…tests, expand test coverage

- Extract FlowConfigError and detect_cycles into config/errors.py; phases/config.py becomes a compat shim
- Move TaskConfig, CheckpointConfig, FlowEntry into config/models.py; replace mutable defaults with Field(default_factory=...)
- Rewrite engine.py: _VarState dataclass, _deduplicate(), seen_files dedup, match-based _registry_for(), phase_discovery_targets(), only insert registry entry when no conflict; fix pending key type to ResourceKind
- Rewrite orchestrator.py: split on_initialize() into 4 helpers; _build_runtime() returns 4-tuple; wrap _agent_logger.close() in try/except in on_finalize()
- agentic_phase.py: replace cast() with assert; add assert for system_prompt_path; import from config.errors/config.models
- goal.py: add _ReviewerOutput model + TypeAdapter; replace manual JSON parse with _REVIEWER_ADAPTER.validate_json()
- inspect_endpoint.py: remove unnecessary try/except around unlink(missing_ok=True); use Path.replace() not os.replace()
- test_engine.py: fix Windows expanduser (set USERPROFILE); fix match string for nonexistent path; add multi-dir merge, user-dir override, overlapping dir dedup, detect_cycles direct tests, _parse_file failure modes, variable resolution, path resolution, conflict source ordering tests
- test_models.py: add test_resource_envelope_unknown_type_raises

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…x strict bool, fix test condition

- inspect_endpoint.py: restore import os and os.replace() (test patches inspect_endpoint.os); wrap unlink() in try/except OSError to handle directory case silently
- goal.py: add strict=True to _ReviewerOutput ConfigDict to prevent Pydantic coercing non-bool JSON values to bool
- test_engine.py: fix test_build_flow_error_paths condition from 'conflict' in match to match == 'conflicts' to avoid triggering the extra-file setup for variable_default_conflict

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dd-octo-sts

dd-octo-sts Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Validation Report

All 21 validations passed.

Show details
Validation Description Status
agent-reqs Verify check versions match the Agent requirements file
ci Validate CI configuration and code coverage settings
codeowners Validate every integration has a CODEOWNERS entry
config Validate default configuration files against spec.yaml
dep Verify dependency pins are consistent and Agent-compatible
http Validate integrations use the HTTP wrapper correctly
imports Validate check imports do not use deprecated modules
integration-style Validate check code style conventions
jmx-metrics Validate JMX metrics definition files and config
labeler Validate PR labeler config matches integration directories
legacy-signature Validate no integration uses the legacy Agent check signature
license-headers Validate Python files have proper license headers
licenses Validate third-party license attribution list
metadata Validate metadata.csv metric definitions
models Validate configuration data models match spec.yaml
openmetrics Validate OpenMetrics integrations disable the metric limit
package Validate Python package metadata and naming
qa-label Validate the pull request declares whether it needs QA for the next Agent release
readmes Validate README files have required sections
saved-views Validate saved view JSON file structure and fields
version Validate version consistency between package and changelog

View full run

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ddev qa/skip-qa Automatically skip this PR for the next QA team/agent-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants