Files
crewAI/lib/cli/tests/test_create_flow.py
T
João MouraandClaude Opus 5.5 ab423144c1 docs: correct deploy and platform-tool guidance in the project AGENTS.md (#8084)
* docs: correct deploy and platform-tool guidance in the project AGENTS.md

The AGENTS.md that `crewai create` ships told coding agents that
`crewai deploy remove <id>` works (the CLI only takes `-u <uuid>`), that a
deploy needs a GitHub repository (with no origin it uploads a ZIP), that
PLATFORM_APPS is the source of truth for action selectors (some of its
action names resolve to no tool), and to measure quality with
`crewai test`. Its router example also declared no labels, so
`crewai flow plot` could not draw the branches.

- Template: platform token, selector syntax, `apps:` YAML example and
  selector check; router labels; deploy prerequisites, `-y`, `.env`
  upload, org commands, `project_id`; best practice points at
  `crewai eval` inside the eval markers.
- Docs: quickstart deploy prerequisite and `remove -u`, and router
  labels in concepts/flows, in en, ar, ko and pt-BR.
- Tests parse every documented deploy/org command against the real CLI,
  run the routing example through the plot builder, and check the best
  practices stay numbered without gaps for crew and tool projects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: base the quickstart ZIP-deploy note on any git origin

The CLI deploys from git whenever an `origin` exists, GitHub or not, and
uploads a ZIP only when there is none. The quickstart said "GitHub
origin ... without one", which reads as if a non-GitHub origin takes the
ZIP path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:22:59 +00:00

108 lines
4.2 KiB
Python

from __future__ import annotations
from pathlib import Path
import runpy
from click.testing import CliRunner
from crewai.flow.visualization import build_flow_structure
from pytest import MonkeyPatch
import tomli
from crewai_cli.cli import crewai
from crewai_cli.create_flow import create_flow
def test_create_flow_declarative_project_can_run(
tmp_path: Path, monkeypatch: MonkeyPatch
):
monkeypatch.chdir(tmp_path)
create_flow("Research Flow", declarative=True)
project_root = tmp_path / "research_flow"
assert project_root.is_dir()
pyproject = tomli.loads(
(project_root / "pyproject.toml").read_text(encoding="utf-8")
)
assert pyproject["project"]["name"] == "research_flow"
assert pyproject["project"]["requires-python"]
assert pyproject["project"]["dependencies"]
assert (project_root / pyproject["tool"]["crewai"]["definition"]).is_file()
agents_md = (project_root / "AGENTS.md").read_text(encoding="utf-8")
assert "CrewAI Flow declaration" in agents_md
assert "schema: crewai.flow/v1" in agents_md
assert "do not assemble the string with CEL `+`" in agents_md
assert "Agent prompt template. Insert Flow values with `${...}`" in agents_md
assert "Runtime inputs passed to the Crew" in agents_md
assert "call: expression" in agents_md
assert "call: tool" not in agents_md
assert "call: script" not in agents_md
assert "call: each" not in agents_md
assert "human_feedback" not in agents_md
claude_md = (project_root / "CLAUDE.md").read_text(encoding="utf-8")
assert "@AGENTS.md" in claude_md.splitlines()
cursor_md = (project_root / "CURSOR.md").read_text(encoding="utf-8")
assert "@AGENTS.md" in cursor_md.splitlines()
gemini_md = (project_root / "GEMINI.md").read_text(encoding="utf-8")
assert "@./AGENTS.md" in gemini_md.splitlines()
monkeypatch.chdir(project_root)
result = CliRunner().invoke(crewai, ["run"], env={"UV_RUN_RECURSION_DEPTH": "1"})
assert result.exit_code == 0
assert "Running the Flow" not in result.output
assert "AI agents" in result.output
def test_create_flow_scaffolds_assistant_instructions(
tmp_path: Path, monkeypatch: MonkeyPatch
):
monkeypatch.chdir(tmp_path)
create_flow("Research Flow")
project_root = tmp_path / "research_flow"
agents_md = (project_root / "AGENTS.md").read_text(encoding="utf-8")
assert "CrewAI Reference for AI Coding Assistants" in agents_md
assert "Never disable, block, or silence CrewAI's built-in observability" in agents_md
claude_md = (project_root / "CLAUDE.md").read_text(encoding="utf-8")
assert "@AGENTS.md" in claude_md.splitlines()
gemini_md = (project_root / "GEMINI.md").read_text(encoding="utf-8")
assert "@./AGENTS.md" in gemini_md.splitlines()
def test_scaffolded_flow_agents_md_tells_assistants_to_evaluate_with_crewai_eval(
tmp_path: Path, monkeypatch: MonkeyPatch
):
monkeypatch.chdir(tmp_path)
create_flow("Research Flow")
create_flow("Declared Flow", declarative=True)
for project in ("research_flow", "declared_flow"):
agents_md = (tmp_path / project / "AGENTS.md").read_text(encoding="utf-8")
assert "## Evaluating this" in agents_md
assert "Run `crewai eval` after a change" in agents_md
assert "it prints a **markdown brief** after the verdict" in agents_md
assert 'crewai eval --models "provider/model,…"' in agents_md
assert "{{name}}" not in agents_md
assert "crewai-eval:" not in agents_md
def test_scaffolded_agents_md_routing_example_lets_plots_see_its_branches(
tmp_path: Path, monkeypatch: MonkeyPatch
):
monkeypatch.chdir(tmp_path)
create_flow("Research Flow")
agents_md = (tmp_path / "research_flow" / "AGENTS.md").read_text(encoding="utf-8")
section = agents_md.split("### Conditional Routing", 1)[1]
example = tmp_path / "routing_example.py"
example.write_text(section.split("```python\n", 1)[1].split("```", 1)[0])
quality_flow = runpy.run_path(str(example), run_name="routing_example")["QualityFlow"]
structure = build_flow_structure(quality_flow())
assert structure["nodes"]["check_quality"]["router_events"] == [
"high_quality",
"needs_revision",
]