This utility converts "specializing agents" between different AI provider formats. Specializing agents are custom modes or sub-agents that allow for more tailored interactions with AI models. This tool currently supports the following formats:
- Kilo Code: Custom modes defined in
custom_modes.yaml. - Gemini CLI: Sub-agents defined as
.tomlfiles. - Claude Code: Sub-agents defined as
.mdfiles with YAML front matter.
The primary purpose of this utility is to streamline the process of migrating and sharing these specialized agents across different platforms, ensuring a consistent experience and reducing the need for manual conversion.
To use this utility, you need to have Python 3 installed. You can install the necessary dependencies using pip and the provided requirements.txt file.
pip install -r requirements.txtThis will install the required PyYAML and toml libraries.
The utility operates by parsing a source agent definition file from one provider, converting it into a normalized, intermediate AgentDefinition format, and then generating a new agent definition file for the target provider.
The core logic is handled by a system of "adapters," where each provider has its own adapter responsible for parsing its specific file format and generating output from the normalized AgentDefinition.
The AgentDefinition class (adapters/base.py) serves as the common data structure, representing key attributes of a specialized agent, such as its slug, name, description, and prompt.
The script agent_converter.py is the main entry point, which dynamically loads all available adapters, parses command-line arguments, and orchestrates the conversion process.
The script is executed from the command line, specifying the file path to the source agent, the source provider, and the target provider.
To convert a Gemini agent to a Claude agent, you would run:
python agent_converter.py -f /path/to/your/gemini-agent.toml -s gemini -t claudeSince Kilo's custom_modes.yaml can contain multiple agents, you need to specify which agent to convert using the --slug argument:
python agent_converter.py -f /path/to/your/custom_modes.yaml -s kilo -t gemini --slug your-agent-slugThe output of the conversion will be printed directly to the console. You can then redirect this output to a file as needed, for example:
python agent_converter.py -f /path/to/your/claude-agent.md -s claude -t kilo --slug new-kilo-agent > new_custom_modes.yamlTo extend the utility to support a new provider, you need to create a new adapter class. Here is a step-by-step guide:
-
Create a New Adapter File: In the
adapters/directory, create a new Python file for your adapter (e.g.,new_provider_adapter.py). -
Implement the Adapter Class: Inside the new file, create a class that inherits from
AbstractAdapter(fromadapters/base.py). This class must implement two methods:parseandgenerate.parse(self, filepath: str, **kwargs) -> AgentDefinition: This method should open and read the source file, parse its content, and return a populatedAgentDefinitionobject.generate(self, agent: AgentDefinition) -> str: This method should take anAgentDefinitionobject and return a string containing the file content for the new provider's format.
-
Example Adapter Structure:
# in adapters/new_provider_adapter.py import logging from adapters.base import AbstractAdapter, AgentDefinition logger = logging.getLogger(__name__) class NewProviderAdapter(AbstractAdapter): """Adapter for NewProvider.""" def parse(self, filepath: str, **kwargs) -> AgentDefinition: """Parses a NewProvider agent file into an AgentDefinition.""" logger.info(f"Parsing NewProvider agent from {filepath}") # Add your parsing logic here # ... return AgentDefinition( slug="new-agent", name="New Agent", description="A new agent.", prompt="Instructions for the new agent.", ) def generate(self, agent: AgentDefinition) -> str: """Generates the file content for a NewProvider agent.""" # Add your generation logic here # ... return f"This is the generated content for {agent.name}."
-
Dynamic Loading: The
agent_converter.pyscript will automatically discover and load your new adapter as long as it is located in theadaptersdirectory and inherits fromAbstractAdapter. The name of the provider will be derived from the filename (e.g.,new_provider_adapter.pywill correspond to thenew_providerchoice in the command-line arguments).