Commit Graph

22 Commits

Author SHA1 Message Date
Vinicius Brasil
1556dbea3e Add generated Flow Definition authoring skill (#6393)
* Add generated Flow Definition authoring skill

Generate a portable skill from the Flow Definition schema so agents can
author valid declarative flows with the same reference CrewAI uses to
validate them. New declarative flow projects now write this skill.

```python
from crewai.flow.flow_definition import FlowDefinition
skill = FlowDefinition.skill(skips=(), examples_format="yaml")
```

* `examples_format` accepts `"yaml"` or `"json"`.
* Supported skips: `conversational`, `non_linear_flows`, `each`, `hitl`, `persistence`, `config`, `expression_action`, `script_action`, `tool_action`

The generated skill includes authoring rules, a routed crew example, and
an API reference extracted from the Flow, action, state, agent, crew,
and task Pydantic schemas.

* Fix declarative flow scaffold without framework import

* Fix skipped expression action guidance

* Fix markdown links in skill
2026-06-30 09:13:33 -07:00
Vinicius Brasil
596150188b Require explicit CrewAI project definitions (#6358)
* Require explicit CrewAI project definitions

JSON crews and declarative flows now resolve from `[tool.crewai]`
metadata instead of implicit filename discovery. This makes project type
selection deterministic, prevents stray `crew.json(c)` files from changing
CLI behavior, and centralizes definition path validation for run, install,
deploy validation, plotting, and memory reset paths.

`[tool.crewai].definition` must be a project-local file path. Absolute
paths, `~`, missing files, directories, and paths escaping the project root
are rejected so deploy and runtime commands use the same contract.

Breaking changes and migration paths:

* JSON crew projects are no longer discovered from `crew.json` or
  `crew.jsonc` alone. Add explicit metadata:

  ```toml
  [tool.crewai]
  type = "crew"
  definition = "crew.jsonc"
  ```

* Declarative flow projects must use a valid project-local definition path:

  ```toml
  [tool.crewai]
  type = "flow"
  definition = "flows/research.yaml"
  ```

* `Flow.from_definition(definition)` is removed. Use:

  ```python
  Flow.from_declaration(contents=definition)
  ```

* `FlowDefinition.to_json()` and `FlowDefinition.to_yaml()` are removed.
  Use `FlowDefinition.to_dict()` and serialize with the caller's JSON or
  YAML library.

* `FlowDefinition.from_dict()` is removed. Use:

  ```python
  FlowDefinition.from_declaration(contents=data)
  ```

* `FlowDefinition.json_schema()` is removed. Use Pydantic's schema API only
  where schema generation is intentionally needed:

  ```python
  FlowDefinition.model_json_schema(by_alias=True)
  ```

* `crewai_cli.run_crew.find_crew_json_file()` and `_has_json_crew()` are
  removed. Use `configured_project_json_crew()` or the shared
  `crewai_core.project.configured_project_definition("crew")` helper.

* `crewai reset-memories` now only loads JSON crews declared through
  `[tool.crewai].definition`, and invalid declared JSON crew definitions
  fail instead of silently falling back to classic crew discovery.

* Address code review comments
2026-06-26 12:07:03 -07:00
Vinicius Brasil
3452e5c187 Add unified declarative flow loading (#6308)
Add a single declaration loader shared by API and CLI callers.

- Add FlowDefinition.from_declaration for FlowDefinition instances, dictionaries, YAML/JSON strings, and file paths
- Add Flow.from_declaration to build runnable flows directly from the same inputs
- Route declarative flow CLI loading through Flow.from_declaration so path handling and validation stay centralized

```
# Load just the serializable definition when you do not need to run it yet.
definition = FlowDefinition.from_declaration(path="flows/research.crewai")
definition = FlowDefinition.from_declaration(contents=flow_yaml)
definition = FlowDefinition.from_declaration(contents=flow_dict)

# Build a runnable flow directly from the same declaration inputs.
flow = Flow.from_declaration(path="flows/research.crewai")
flow = Flow.from_declaration(contents=flow_yaml)
flow = Flow.from_declaration(contents=flow_dict)
flow = Flow.from_declaration(contents=definition)

# Run it like any other flow.
result = flow.kickoff(inputs={"topic": "AI agents"})

# The CLI now goes through the same path-based loader.
# crewai run --definition flows/research.crewai
```
2026-06-23 12:02:18 -07:00
Vinicius Brasil
0391febc6c Allow @router() as start method of a flow (#6288)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
This commit fixes a bug where a router method could not be the start
method of a flow.

This is useful when you want to route against the initial state, or even
stack two routers.
2026-06-22 14:04:45 -07:00
Vinicius Brasil
bc2c2a858c Add single agent action to Flow definitions (#6226)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
* Add single agent action to Flow definitions

Lets a flow method build and run a single CrewAI agent directly, without
wrapping it in a crew. Same idea as the existing `crew` action, but for
one agent.

  methods:
    answer:
      do:
        call: agent
        with:
          role: Analyst
          goal: Answer questions
          backstory: Knows things.
          input: "${state.question}"
      start: true

* `input` is required and interpolated from flow state, like
  `${state.question}` or `${item}` inside an `each` loop
* optional `response_format` points at a Pydantic model (`{"python":
  "models.AnswerModel"}`) to get structured output
* `input` must be a string and its CEL is validated at load time, so bad
  expressions like `${state.}` fail early

* Simplify test code
2026-06-18 14:53:33 -07:00
Vinicius Brasil
b5e23a87f2 Add optional if expression to each.do steps (#6214)
* Use explicit name/action shape for each.do steps

* Add optional `if` expression to `each.do` steps

Lets a step inside an `each` action run conditionally based on a CEL
expression evaluated against `item` and prior step `outputs`.
2026-06-18 10:33:13 -07:00
Vinicius Brasil
218dc82bf7 Replace flow diagnostics with logging (#6212)
This commit removes flow diagnostics from the definition. These were
used for logging only, and should not be coupled to the definition.
2026-06-17 19:37:52 -07:00
Vinicius Brasil
7374486f00 Document FlowDefinition fields in the JSON schema (#6198)
Add a description and examples to every FlowDefinition field and
standardize on `typing.Literal`, so the generated JSON schema documents
itself — each action discriminator, state branch, and config option
explains what it is and shows a realistic value.

Examples live on individual fields only, never at the model level, which
keeps the schema readable for tooling that renders field-level help.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:49:01 -07:00
Vinicius Brasil
5bd10ee2c4 Add script/code block action to FlowDefinition (#6197)
* Add script/code blocks to FlowDefinition

Let a Flow method run trusted inline Python with `call: script`. The code
is compiled once into a generated function and receives the runtime
values as arguments.

```yaml
methods:
  normalize:
    start: true
    do:
      call: script
      code: |
        import math
        state["rounded"] = math.ceil(state["raw_score"])
        return f"rounded:{state['rounded']}"
```

Even though this shares the same surface of tools (custom code), I
decided to make it opt-in for now, using
`CREWAI_ALLOW_FLOW_SCRIPT_EXECUTION=1`.

* Address code review comments
2026-06-17 18:38:41 -07:00
Vinicius Brasil
7bb9bc7e1a Discriminate FlowDefinition state types (#6196)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Replace the single FlowStateDefinition model with a `type`-discriminated
union of FlowDictStateDefinition, FlowPydanticStateDefinition,
FlowJsonSchemaStateDefinition, and FlowUnknownStateDefinition.

Each branch only carries the fields it actually uses and forbids extras,
so an invalid combination like a `dict` state with a `ref` now fails
validation instead of being silently accepted. The runtime reads `ref`
and `json_schema` defensively since they no longer exist on every branch.

```yaml
state:
  type: json_schema
  json_schema:
    type: object
    properties:
      topic:
        type: string
```

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:31:07 -07:00
Vinicius Brasil
4eb90ffbf3 Add crew actions to FlowDefinition (#6184) 2026-06-16 12:59:48 -07:00
Vinicius Brasil
fe2c236601 Add each composite action to FlowDefinition (#6164)
Lets a definition loop over an array without writing Python. Each
iteration exposes `item` and prior steps `outputs`.

```yaml
do:
  call: each
  in: state.rows
  do:
    - normalize:
        call: tool
        ref: my_tools:NormalizeRowTool
        with: { row: "${ item }" }
    - lead_scoring:
        call: agent
        # ...
```
2026-06-15 21:44:33 -07:00
Vini Brasil
6ad821b157 Add expressions to FlowDefinition actions (#6145)
* Add expressions to FlowDefinition actions

Let definitions compute values without Python. A new `call: expression`
action evaluates a Common Expression Language (CEL) expression, and tool
`with:` blocks now render `${...}` CEL templates.

Example 1:

```yaml
decide:
  do:
    call: expression
    expr: "state.score >= 80 ? 'qualified' : 'nurture'"
  router: true
  emit: [qualified, nurture]
```

Example 2:

```yaml
search:
  do:
    call: tool
    ref: my.pkg:SearchTool
    with:
      search_query: "${outputs.build_query.query + ' news'}"
      max_results: "${state.limit}"
```

* Address code review comments

* Address code review comments

* Fix linting offenses

* Address code review comments

* Fix scrapgraph issue
2026-06-12 21:56:02 -07:00
Vini Brasil
2444895ca4 Implement Flow definition run tools without Python code (#6144)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
A `do:` step can now say `call: tool` and name a CrewAI tool to run,
passing its inputs under `with:`. Before this, a definition could only
point at Python code to run.

```yaml
methods:
  search:
    start: true
    do:
      call: tool
      ref: crewai_tools:ExaSearchTool
      with:
        search_query: ai agents
```
2026-06-12 19:47:58 -07:00
Vini Brasil
373dca3d04 Run flows from a definition without a Python subclass (#6104)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
* Read flow dispatch from FlowDefinition

Store the definition in a `_definition` PrivateAttr at post-init and
convert the dispatch helpers (`_start_method_names`, `_listener_methods`,
`_start_condition`, `_listen_condition`, `_is_router`) from classmethods
to instance methods that read it. Event names now fall back to
`self._definition.name` instead of `self.__class__.__name__`.

Behavior is identical for decorator subclasses, but the engine no longer
assumes the definition comes from the class. This is the seam for
`Flow.from_definition`, where an instance runs a definition that was
loaded rather than built from a Python subclass.

* Add Flow.from_definition to run flows without a subclass

A FlowDefinition (e.g. loaded from YAML) was only usable for dispatch on
decorator-authored subclasses. Now each method definition records an
importable `module:qualname` handler ref, and `Flow.from_definition`
resolves and binds those handlers to build a runnable flow directly.

* Build flow state from FlowDefinition

Definition-driven flows previously always started with a bare dict
state.

* Replace handler string with structured FlowActionDefinition

`handler: str | None` was optional and opaque — missing handlers only
surfaced at kickoff time. `do: FlowActionDefinition` is required, so
Pydantic rejects invalid definitions at parse time.

The `call: "code"` discriminator prepares the schema for future
non-Python action types (e.g. MCP tool, crew) without touching
`FlowMethodDefinition`. Resolution logic is extracted to
`runtime/_action_resolvers.py` to keep the dispatch point isolated.

* Fix conversational start router missing required do field

FlowMethodDefinition.do became required when the handler string was
replaced with FlowActionDefinition, but _conversation_start_router still
built its fragment without it, breaking crewai import entirely.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add event scoping to flow test

* Change lib/crewai/tests/test_flow_from_definition.py

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 14:18:49 -07:00
Lorenze Jay
b6e5d632c1 improve convo routing cycle with one less route (#6102)
* improve one less route

* flows in flows, new agent executor causing early trace batch finalization

* addressing comments

* addressing comments pt2

* lint and typecheck fix
2026-06-10 16:49:16 -07:00
Lorenze Jay
f214ff4b7b decouple convo logic from runtime and added a conversational_definition (#6091)
* decouple convo logic from runtime and added a conversational_definition

* type check fix

* always defer traces for convo and so fix tests to reflect that
2026-06-10 10:49:39 -07:00
Vini Brasil
703ffe67ee Migrate @listen/@router runtime to read from FlowDefinition (#6084)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
* Migrate @listen/@router runtime to read from FlowDefinition

The runtime now resolves listener conditions, router status, and emit
values from `FlowMethodDefinition` instead of legacy method metadata and
the `_listeners`/`_routers`/`_router_emit` registries.

* Evaluate AND/OR listener conditions over the definition shape via
  `_evaluate_definition_condition`
* Drop the class registries and the `FlowMeta` extraction that built
  them; stop stamping `__trigger_methods__`, `__is_router__`,
  `__router_emit__`, and friends
* `@human_feedback` emit now lives only on its config

* Simplify conditionals DSL
2026-06-09 09:40:30 -07:00
Vini Brasil
e570534f15 Migrate @start to read from FlowDefinition (#6071)
* Remove `_start_methods` and `__is_start_method__` stamping
* Add helpers to read start info from the definition
* Scan `__dict__` instead of `dir()` to find flow methods
2026-06-08 15:03:50 -07:00
Vini Brasil
906cd9769d feat(flow): type DSL triggers as route-aware decorators (#6042)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Centralize FlowTrigger and FlowMethodDecorator so start/listen/router and the boolean trigger helpers share one authoring contract. This preserves decorated method signatures for static checking while allowing route-label strings in nested FlowCondition data.

Export the shared typing helpers for static analyzers, use an explicit Protocol body, align condition validation with Sequence-backed condition data, and drop the stale call-arg ignore exposed by the signature-preserving decorators.

Update the flow guide to use or_(...) for multi-label listeners.
2026-06-04 18:07:49 -03:00
Vini Brasil
75dad212a2 Split flow DSL monolith into focused decorator modules (#6040)
The Flow DSL lived in one 1033-line `dsl.py` that mixed every decorator
(`@start`/`@listen`/`@router`), the `human_feedback` decorator,
condition combinators, and FlowDefinition extraction helpers in a single
file.

Split it into a `dsl/` package where each decorator gets its own module
(`start.py` 68 lines, `listen.py` 55, `router.py` 164,
`human_feedback.py` 98) and the shared extraction/condition helpers stay
in `utils.py`. The public API is re-exported from `dsl/__init__.py`, so
import paths are unchanged.

This is simpler because each decorator is now read and changed in
isolation instead of scanning a 1000-line file to find one of them, and
router-specific annotation parsing no longer sits next to unrelated
start/listen logic.
2026-06-04 15:02:06 -03:00
Vini Brasil
051fa0c1cb Build FlowDefinition from Flow DSL metadata (#6017)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* Build FlowDefinition from Flow DSL metadata

Introduce `FlowDefinition`, a serializable model built from the Flow
DSL's runtime metadata. It becomes the structural contract for Flow
methods, triggers, routers, state, and configuration.

The visualization layer is the first consumer: `flow_structure` and
`build_flow_structure` now project from the definition instead of
re-introspecting the class. The runner still executes from live
registries, but the definition gives future runners a single static
contract to read.

This replaces AST source parsing for router return values, crew
references, and state schema with runtime metadata plus explicit
`@router(paths=...)` or `Literal`/`Enum` return hints. AST parsing was
fragile and could silently fail for dynamic or non-inspectable methods.

The refactor removes obsolete introspection and serializer code:

* Delete `flow_serializer.py`, `flow/utils.py`, and
  `visualization/schema.py`
* Move flow structure modeling into `flow_definition.py`
* Simplify visualization building around the static definition contract

* Format files
2026-06-03 18:02:56 -03:00