mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-10-22 18:03:10 +02:00
* 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>
108 lines
4.2 KiB
Python
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",
|
|
]
|