Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
381 changes: 84 additions & 297 deletions lib/cli/src/crewai_cli/create_json_crew.py

Large diffs are not rendered by default.

23 changes: 17 additions & 6 deletions lib/cli/src/crewai_cli/run_crew.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@

import click
from crewai_core.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
from crewai_core.project import (
ProjectDefinitionError,
configured_project_definition,
get_crewai_project_type,
read_toml,
)
from packaging import version

from crewai_cli.utils import (
Expand Down Expand Up @@ -102,11 +96,28 @@ def _full_crewai_install_error() -> click.ClickException:
return click.ClickException(_FULL_CREWAI_INSTALL_MESSAGE)


def read_toml(*args: Any, **kwargs: Any) -> dict[str, Any]:
from crewai_core.project import read_toml as _read_toml

return _read_toml(*args, **kwargs)


def get_crewai_project_type(pyproject_data: dict[str, Any]) -> str | None:
from crewai_core.project import get_crewai_project_type as _get_crewai_project_type

return _get_crewai_project_type(pyproject_data)


def configured_project_json_crew(
pyproject_data: dict[str, Any] | None = None,
project_root: Path | None = None,
) -> Path | None:
"""Return the configured JSON crew definition for crew projects."""
from crewai_core.project import (
ProjectDefinitionError,
configured_project_definition,
)

root = project_root or Path.cwd()
if pyproject_data is None and not (root / "pyproject.toml").is_file():
return None
Expand Down
4 changes: 4 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.env
__pycache__/
.DS_Store
report.md
20 changes: 20 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# {{name}}

A crewAI project using JSON-first configuration.

## Running

```bash
crewai run
```

## Project Structure

- `agents/` - Agent definitions (JSONC)
- `crew.jsonc` - Crew definition with tasks and configuration
- `tools/` - Custom tools (Python)
- `knowledge/` - Knowledge files for agents

> **Note:** `custom:<name>` tool references execute `tools/<name>.py` as local
> Python code when the crew loads. Only run crew projects from sources you
> trust.
59 changes: 59 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/agent.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
// Agent's role title — appears in prompts and logs.
// You can use {placeholder} inputs in role, goal, or backstory.
// Example: "role": "Senior {industry} Researcher"
"role": {{role_json}},

// Optional custom Agent subclass
// "type": {"python": "my_project.agents.CustomAgent"},

// The agent's primary objective
"goal": {{goal_json}},

// Background story that shapes the agent's personality and approach
"backstory": {{backstory_json}},

// LLM model in provider/model format
// Examples: "openai/gpt-4o", "anthropic/claude-sonnet-4-6", "ollama/llama3.3"
// For custom endpoints or deployment-based providers, replace with:
// "llm": {"model": "llama3", "provider": "ollama", "base_url": "http://localhost:11434"},
// "llm": {"deployment_name": "my-deployment", "provider": "azure", "api_version": "2024-10-21"},
"llm": {{llm_json}},

// Override LLM used specifically for tool/function calling
// "function_calling_llm": "openai/gpt-5.4-mini",

// Tools available to this agent
// Built-in: "SerperDevTool", "ScrapeWebsiteTool", "FileReadTool", etc.
// Custom: "custom:my_tool" loads from tools/my_tool.py
"tools": {{tools_json}},

// Optional agent-level guardrail — validates this agent's final output.
// String guardrails are checked by an LLM and can reject/retry output.
// Python refs must point to module-level functions/classes in trusted code.
// "guardrail": "Only answer with information supported by retrieved evidence.",
// "step_callback": {"python": "my_project.callbacks.on_agent_step"},
// "guardrail_max_retries": 2,

// Advanced agent options:
// Docs: https://docs.crewai.com/concepts/agents
// "reasoning": true,
// "max_reasoning_attempts": 3,
// "planning_config": {
// "reasoning_effort": "medium",
// "llm": {"model": "deepseek-chat", "provider": "deepseek"}
// },
// "multimodal": false,
// "allow_code_execution": false,
// "code_execution_mode": "safe",
// "knowledge_sources": [],
// "knowledge_config": {},
// "inject_date": true,
// "date_format": "%Y-%m-%d",
// "security_config": {},

// Agent behavior settings
"settings": {
{{settings_block}}
}
}
Comment thread
vinibrsl marked this conversation as resolved.
35 changes: 35 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/agent_settings.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Show detailed execution logs
"verbose": false,

// Allow this agent to delegate tasks to other agents in the crew
"allow_delegation": {{allow_delegation}}{{delegation_comma}}

// Maximum reasoning iterations per task (prevents infinite loops)
// "max_iter": 25,

// Maximum tokens for agent's response generation
// "max_tokens": null,

// Maximum execution time in seconds
// "max_execution_time": null,

// Maximum LLM requests per minute (rate limiting)
// "max_rpm": null,

// Enable agent-level memory (persists across tasks)
// "memory": false,

// Cache tool results to avoid duplicate calls
// "cache": true,

// Auto-summarize context when it exceeds the LLM's context window
// "respect_context_window": true,

// Maximum retries on execution errors
// "max_retry_limit": 2,

// Enable step-by-step planning before task execution
{{planning_line}}

// Include system prompt in LLM calls
// "use_system_prompt": true
58 changes: 58 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/crew.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
// Display name for this crew
"name": {{name_json}},

// Agents to include — each must have a matching agents/<name>.jsonc file
"agents": {{agent_names_json}},

// Task definitions — executed in order for sequential process
"tasks": [
{{tasks_fragments}}
],

// Execution process
// "sequential" — tasks run in order, each receiving prior task outputs
// "hierarchical" — a manager agent delegates tasks (requires manager_llm)
"process": {{process_json}},

// Enable verbose logging during execution
"verbose": true,

// Enable crew memory — persists context and learnings across tasks
"memory": {{memory}},

// Automatically plan the execution strategy before running tasks
// "planning": false,

// LLM for the planning step (used when planning is true)
// "planning_llm": "openai/gpt-4o",

// LLM for the manager agent (required when process is "hierarchical")
// "manager_llm": "openai/gpt-4o",

// Crew-level LLM fields also accept object form for custom endpoints
// "chat_llm": {"model": "llama3", "provider": "ollama", "base_url": "http://localhost:11434"},

// Advanced crew options:
// Docs: https://docs.crewai.com/concepts/crews
// For hierarchical crews, manager_agent can reference an agents/<name>.jsonc file
// that is not included in the "agents" list.
// "manager_agent": "{{manager_agent_name}}",
// "before_kickoff_callbacks": [{"python": "my_project.callbacks.before_kickoff"}],
// "after_kickoff_callbacks": [{"python": "my_project.callbacks.after_kickoff"}],
// "function_calling_llm": "openai/gpt-4o-mini",
// "max_rpm": null,
// "cache": true,
// "knowledge_sources": [],
// "embedder": {},
// "output_log_file": "crew.log",
// "stream": false,
// "tracing": false,
// "security_config": {},

// Optional runtime input defaults.
// Use {placeholder} in agent or task text, for example:
// "description": "Research {topic} and write a brief"
// `crewai run` prompts for any placeholders missing from this object.
"inputs": {{inputs_json}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Add your knowledge files here
20 changes: 20 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[project]
name = "{{folder_name}}"
version = "0.1.0"
description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<3.14"
dependencies = [
"{{crewai_tools_dependency}}"
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
only-include = ["agents", "crew.jsonc", "tools", "knowledge", "skills"]

[tool.crewai]
type = "crew"
definition = "crew.jsonc"
40 changes: 40 additions & 0 deletions lib/cli/src/crewai_cli/templates/json_crew/task.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
// Task identifier
"name": {{name_json}},

// What the task should accomplish
// Use {placeholder} inputs here; crewai run prompts for missing values
"description": {{description_json}},

// Clear definition of what the output should look like
"expected_output": {{expected_output_json}},

// Optional task guardrail(s) validate output before completion
// Use "guardrail" for one rule or "guardrails" for many
// Failed guardrails retry up to guardrail_max_retries times
// "guardrail": "Every factual claim needs context support.",
// "guardrails": [
// "Every factual claim must be supported by context.",
// "The answer must match the expected output format."
// ],
// "guardrail_max_retries": 2,

// Advanced task options:
// Docs: https://docs.crewai.com/concepts/tasks
// "type": "ConditionalTask",
// "condition": { "python": "my_project.conditions.should_run" },
// "output_json": { "python": "my_project.models.ReportOutput" },
// "output_pydantic": null,
// "response_model": null,
// "converter_cls": { "python": "my_project.converters.CustomConverter" },
// "markdown": false,
// "input_files": { "brief": "data/brief.txt" },
// "security_config": {},

// Which agent handles this task
"agent": {{agent_json}}{{agent_comma}}{{context_block}}{{output_file_block}}

// "tools": [],
// "human_input": false,
// "async_execution": false
}
29 changes: 21 additions & 8 deletions lib/cli/src/crewai_cli/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

from collections.abc import Mapping
import os
from pathlib import Path
import re
import shutil
from typing import Any

Expand Down Expand Up @@ -35,13 +37,15 @@
"load_env_vars",
"parse_toml",
"read_toml",
"render_template",
"tree_copy",
"tree_find_and_replace",
"write_env_file",
]


console = Console()
_TEMPLATE_TOKEN_RE = re.compile(r"{{([a-zA-Z_][a-zA-Z0-9_]*)}}")


def is_dmn_mode_enabled() -> bool:
Expand Down Expand Up @@ -69,14 +73,14 @@ def copy_template(
src: Path, dst: Path, name: str, class_name: str, folder_name: str
) -> None:
"""Copy a file from src to dst."""
with open(src, "r") as file:
content = file.read()

content = content.replace("{{name}}", name)
content = content.replace("{{crew_name}}", class_name)
content = content.replace("{{folder_name}}", folder_name)
content = content.replace(
"{{crewai_tools_dependency}}", get_crewai_tools_dependency()
content = render_template(
src,
{
"name": name,
"crew_name": class_name,
"folder_name": folder_name,
"crewai_tools_dependency": get_crewai_tools_dependency(),
},
)

with open(dst, "w") as file:
Expand All @@ -85,6 +89,15 @@ def copy_template(
click.secho(f" - Created {dst}", fg="green")


def render_template(src: Path, replacements: Mapping[str, str]) -> str:
"""Render a template file using ``{{placeholder}}`` replacements."""
content = src.read_text(encoding="utf-8")
return _TEMPLATE_TOKEN_RE.sub(
lambda match: replacements.get(match.group(1), match.group(0)),
content,
)


def fetch_and_json_env_file(env_file_path: str = ".env") -> dict[str, Any]:
"""Fetch the environment variables from a .env file and return them as a dictionary."""
try:
Expand Down
Loading
Loading