agentic_fabric.runners.base¶
Base runner interface for framework-specific implementations.
All runners must implement this interface to ensure consistent behavior across CrewAI, LangGraph, and Strands.
Runner Implementation Guide¶
To create a new runner for a framework:
Subclass BaseRunner:
from agentic_fabric.runners.base import BaseRunner class MyFrameworkRunner(BaseRunner): framework_name = "myframework"
Implement required methods:
build_fabric_agent()- Convert universal config to a runtime-native fabric agentrun()- Execute the fabric agent and return string outputbuild_agent()- Create framework-specific agentbuild_task()- Create framework-specific task
Register in decomposer (core/decomposer.py):
Add to
FRAMEWORK_PRIORITYAdd case to
get_runner()
Add optional dependency (pyproject.toml):
[project.optional-dependencies] myframework = ["myframework-package>=1.0"]
Example Runner¶
class SimpleRunner(BaseRunner):
framework_name = "simple"
def __init__(self):
try:
import simple_framework
except ImportError as e:
raise RuntimeError("simple_framework not installed") from e
def build_fabric_agent(self, fabric_agent_config):
# Use dict to allow lookup by agent name
agents = {
name: self.build_agent(cfg)
for name, cfg in fabric_agent_config.get("agents", {}).items()
}
tasks = []
for task_name, task_cfg in fabric_agent_config.get("tasks", {}).items():
agent_name = task_cfg.get("agent")
agent = agents[agent_name]
tasks.append(self.build_task(task_cfg, agent))
return {"agents": list(agents.values()), "tasks": tasks}
def run(self, fabric_agent, inputs):
# Execute and return string
return "Result from simple framework"
def build_agent(self, agent_config, tools=None):
return {"role": agent_config["role"], "tools": tools or []}
def build_task(self, task_config, agent):
return {"description": task_config["description"], "agent": agent}
Module Contents¶
Classes¶
Abstract base class for framework runners. |
API¶
- class agentic_fabric.runners.base.BaseRunner¶
Bases:
agentic_fabric.capabilities.AgentCapabilityProviderMixin,abc.ABCAbstract base class for framework runners.
Each framework runner converts agentic-fabric’s universal fabric agent format into framework-specific objects and executes them.
Attributes: framework_name: String identifier for this framework (e.g., “crewai”, “langgraph”, “strands”). Used for logging and framework selection.
Example: Basic runner usage with auto-detection:
```python from agentic_fabric.core.decomposer import get_runner # Auto-detect best available framework runner = get_runner() fabric_agent_config = { "name": "research_fabric_agent", "agents": { "researcher": { "role": "Senior Researcher", "goal": "Find comprehensive information", "backstory": "Expert researcher with years of experience" } }, "tasks": { "research_task": { "description": "Research the topic thoroughly", "expected_output": "Detailed research report", "agent": "researcher" } } } # Build and run in one step result = runner.build_and_run(fabric_agent_config, {"topic": "AI safety"}) print(result) ```- framework_name: str = 'base'¶
- abstractmethod build_fabric_agent(fabric_agent_config: dict[str, Any]) Any¶
Build a framework-specific fabric agent from configuration.
This is the main method that converts agentic-fabric’s universal YAML-based fabric agent configuration into the framework’s native objects.
Args: fabric_agent_config: Universal fabric agent configuration dict containing: - name (str): Fabric agent name for identification - description (str): What the fabric agent does - agents (dict): Dict mapping agent names to agent configs. Each agent config has: - role (str): Agent’s role/title - goal (str): What the agent aims to achieve - backstory (str): Agent’s background/expertise - tools (list[str], optional): Tool names to enable - llm (str, optional): Model override - allow_delegation (bool, optional): Can delegate to others - tasks (dict): Dict mapping task names to task configs. Each task config has: - description (str): What to do - expected_output (str): What output looks like - agent (str): Name of agent to execute this task - context (list[str], optional): Names of prior tasks - knowledge_paths (list[Path], optional): Directories with knowledge files (.md, .txt, etc.) - process (str, optional): “sequential” or “hierarchical” - required_framework (str, optional): Enforced framework
Returns: Framework-specific fabric agent object. Type varies by framework: - CrewAI: crewai.Crew - LangGraph: Compiled StateGraph - Strands: strands.Agent
Raises: ValueError: If configuration is invalid (e.g., unknown agent referenced in task). RuntimeError: If framework is not available.
Example:
python runner = CrewAIRunner() fabric_agent = runner.build_fabric_agent({ "name": "writer_fabric_agent", "agents": { "writer": { "role": "Technical Writer", "goal": "Create clear documentation", "backstory": "10 years writing experience" } }, "tasks": { "write_docs": { "description": "Write API documentation for {topic}", "expected_output": "Markdown documentation file", "agent": "writer" } } })
- abstractmethod run(fabric_agent: Any, inputs: dict[str, Any]) str¶
Execute the fabric agent with inputs.
Runs the previously built fabric agent with the given inputs. This method handles the framework-specific execution and normalizes the output to a string.
Args: fabric_agent: Framework-specific fabric agent object from build_fabric_agent(). Type depends on framework: - CrewAI: crewai.Crew instance - LangGraph: Compiled StateGraph - Strands: strands.Agent instance inputs: Input dict to pass to the fabric agent. Keys are typically variable names used in task descriptions (e.g., {topic} in description becomes inputs[“topic”]).
Returns: Fabric agent output as a string. For complex outputs, the raw text is returned; parsing is left to the caller.
Raises: RuntimeError: If fabric agent execution fails.
Example: ```python # CrewAI runner example result = runner.run(fabric_agent, {“topic”: “machine learning”}) print(result) # “## Machine Learning Report\n\n…”
# LangGraph runner example result = runner.run(graph, {"input": "analyze this code"}) ```
- build_and_run(fabric_agent_config: dict[str, Any], inputs: dict[str, Any] | None = None) str¶
Convenience method to build and run in one step.
Args: fabric_agent_config: Fabric agent configuration. inputs: Optional inputs for the fabric agent.
Returns: Fabric agent output as string.
- abstractmethod build_agent(agent_config: dict[str, Any], tools: list | None = None) Any¶
Build a framework-specific agent.
Creates a single agent from the universal configuration. Called by build_fabric_agent() for each agent in the fabric agent.
Args: agent_config: Agent configuration dict containing: - role (str): Agent’s role/title (e.g., “Senior Researcher”) - goal (str): What the agent aims to achieve - backstory (str): Agent’s background and expertise - llm (str, optional): Model name to override default - allow_delegation (bool, optional): Can delegate tasks - verbose (bool, optional): Enable verbose output tools: Optional list of tool instances to give the agent. Tools should already be resolved/instantiated.
Returns: Framework-specific agent object: - CrewAI: crewai.Agent - LangGraph: Compiled ReAct agent graph - Strands: strands.Agent
Example:
python # CrewAI agent = runner.build_agent({ "role": "Data Analyst", "goal": "Analyze data and provide insights", "backstory": "Expert in statistical analysis" }, tools=[search_tool, calculator_tool])
- abstractmethod build_task(task_config: dict[str, Any], agent: Any) Any¶
Build a framework-specific task.
Creates a single task from the universal configuration. Called by build_fabric_agent() for each task in the fabric agent.
Note: Some frameworks (like CrewAI) support additional parameters beyond the base signature. Subclasses may extend this method with optional parameters like
contextfor task dependencies.Args: task_config: Task configuration dict containing: - description (str): What the task should accomplish. Can include {placeholders} for runtime inputs. - expected_output (str): Description of expected output format - async_execution (bool, optional): Run asynchronously - human_input (bool, optional): Request human feedback agent: Framework-specific agent to assign to this task. Must be the return value from build_agent().
Returns: Framework-specific task object: - CrewAI: crewai.Task - LangGraph: dict (tasks are stored as config) - Strands: dict (tasks are stored as config)
Example: ```python # Basic task task = runner.build_task({ “description”: “Research {topic} thoroughly”, “expected_output”: “Comprehensive research report” }, agent=researcher_agent)
# CrewAI with context (extended signature) task = crewai_runner.build_task( task_config, agent, context=[prior_research_task] # CrewAI-specific ) ```
- get_llm(model: str | None = None) Any¶
Get the LLM for this framework.
Retrieves or creates an LLM instance. The default implementation uses agentic-fabric’s shared LLM configuration. Subclasses may override for framework-specific LLM handling.
Args: model: Optional model name override. If None, uses DEFAULT_MODEL from agentic_fabric.config.llm (usually claude-sonnet-4-20250514).
Returns: Framework-specific LLM object, or None if the LLM module is not available (framework may have its own default). - CrewAI: LiteLLM-compatible LLM - LangGraph: langchain ChatModel - Strands: Uses model_id directly
Example: ```python # Use default model llm = runner.get_llm()
# Use specific model llm = runner.get_llm("claude-haiku-4-5-20251001") # In LangGraphRunner (overridden) llm = runner.get_llm("claude-sonnet-4-20250514") # Returns ChatAnthropic ```
- agent_capabilities: ClassVar[collections.abc.Mapping[str, agentic_fabric.capabilities.AgentCapabilitySpec]] = None¶
- agent_capability_methods: ClassVar[collections.abc.Mapping[str, str]] = None¶
- classmethod list_capabilities(*, kind: str | None = None) tuple[agentic_fabric.capabilities.AgentCapabilitySpec, ...]¶
- call_capability(name: str, *args: Any, **kwargs: Any) Any¶
- capability_map() collections.abc.Mapping[str, agentic_fabric.capabilities.AgentCapabilitySpec]¶